티스토리 뷰

 

틀린 코드

#include <string>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;

int solution(string str1, string str2) {
    int answer = 0;
    int i = 0;
    std::transform(str1.begin(), str1.end(),str1.begin(), (int(*)(int))tolower);
    std::transform(str2.begin(), str2.end(),str2.begin(), (int(*)(int))tolower);
    
    map< string, int > news;
    string temp = "";
    
    for(i = 0; i<str1.length()-1; i++){
        if ((str1[i] >= 97 && str1[i] <= 122) && (str1[i+1] >= 97 && str1[i+1] <= 122)) {
            temp = str1.substr(i, 2);
            news[temp] += 1;
        }
    }
    
    for(i = 0; i < str2.length()-1; i++){
        if ((str2[i] >= 97 && str2[i] <= 122) && (str2[i+1] >= 97 && str2[i+1] <= 122)){
            temp = str2.substr(i, 2);
            news[temp] += 1;
        }
    }
    
    int freq = 0;
    for(auto i = news.begin(); i != news.end(); i++){
        cout << i->first << "  " << i->second << endl;
        if(i->second > 1) freq += 1;
    }
    
    if(news.size() == 0 ) return 65536;
    if(freq == 0) return 0;
    
    answer = floor(((double)freq/news.size()) * 65536);
    return answer;
}

근데 map으로 하면 안됐다.

aa1+aa2

AAAA12

위와 같은 경우 str1 = {aa, aa} str2 = {AA, AA, AA}

이렇게 나오면 합집합은 5개 교집합은 2개로 계산해야하는데 

모두 소문자로 바꾸고 빈도수를 체크하니까 교집합 합집합 모두 1로 나온다.

 

그래서 다음 생각한 것은 unique와 erase 함수를 이용하는 것이다.

str1, str2 벡터를 합치고 unique를 통해서 나간 것은 교집합, (str1 + str2) - 교집합이 합집합이라고 생각했다.

근데 이 방법도 안되는 방법이었다. 결국 만약 중복되는 값이 여러 개라면 다 나가고 하나만 남겨지게 되기 때문이다.

 

 

 

 

완성 코드

 

그래서 이제 나온 것은 find 함수로 중복되는 값을 찾고 없애주면서 하나하나씩 찾는 것이다.

#include <string>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
using namespace std;

int solution(string str1, string str2) {
    int answer = 0;
    int i = 0;
    string temp = "";
    vector<string> str1_arr;
    vector<string> str2_arr;
    
    std::transform(str1.begin(), str1.end(),str1.begin(), (int(*)(int))tolower);
    std::transform(str2.begin(), str2.end(),str2.begin(), (int(*)(int))tolower);
    
    for(i = 0; i<str1.length()-1; i++){
        if ((str1[i] >= 97 && str1[i] <= 122) && (str1[i+1] >= 97 && str1[i+1] <= 122)) {
            temp = str1.substr(i, 2);
            str1_arr.push_back(temp);
        }
    }
    
    for(i = 0; i < str2.length()-1; i++){
        if ((str2[i] >= 97 && str2[i] <= 122) && (str2[i+1] >= 97 && str2[i+1] <= 122)){
            temp = str2.substr(i, 2);
            str2_arr.push_back(temp);
        }
    }
    
    if(str1_arr.size() == 0 && str2_arr.size() == 0) return 65536;
    
    int uunion = str1_arr.size() + str2_arr.size();
    int freq = 0;
    for(auto i = str1_arr.begin(); i!=str1_arr.end(); i++){
        auto j = find(str2_arr.begin(), str2_arr.end(), *i);
        if( j != str2_arr.end()){
            str2_arr.erase(j);
            freq += 1;
        } 
    }
    if(freq == 0) return 0;
    uunion = uunion - freq;
    answer = floor(((double)freq/uunion) * 65536);
    return answer;
}

1. 모두 소문자로 바꿔준다.

2. 소문자 외에 문자가 포함되지 않도록 두 글자씩 끊어서 각각의 벡터에 넣어준다.

3. str1을 기준으로 str2에 중복되는 문자가 있는지 확인하고 지우고를 반복한다.

4. 합집합은 str1, str2 벡터 크기를 더한 값에 중복되는 교집합 크기만큼 빼주면 된다.

5. 교집합이 없는 경우는 0 리턴

6. str1, str2 둘 다 비어있는 경우는 합집합이 0 이므로 65536을 리턴한다.

댓글