본문 바로가기

Algorithm/카카오기출

[프로그래머스] 뉴스 클러스터링 / append, find, isalpha, transform

문제

 

 

풀이

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

vector<string> v(string str){
    char before= tolower(str[0]);
    vector<string> vec;
    for(int i=1; i<str.size(); i++){
        if((before < 'a' || before > 'z') 
           || (tolower(str[i]) < 'a' || tolower(str[i]) > 'z')) {
            before = tolower(str[i]);
            continue;
        }
        string s;
        s.append(1, before).append(1, tolower(str[i]));
        vec.push_back(s);
        before = tolower(str[i]);
    }
    return vec;

}

int solution(string str1, string str2) {
    float answer = 0;
    int inter = 0, uni = 0; // 교, 합집합

    vector<string> vec1,vec2 ;
    vec1 = v(str1);
    vec2 = v(str2);
    uni += vec1.size() + vec2.size();
    if(uni == 0) return 65536;

    for(int i=0; i<vec1.size(); i++){
        if(find(vec2.begin(), vec2.end(), vec1[i]) != vec2.end()){
            inter++;
            vec2.erase(find(vec2.begin(), vec2.end(), vec1[i]));
            vec1.erase(vec1.begin() + i--);
        }
    }
    cout << endl;
    uni -= inter;
    answer = (float)inter/uni;

    return answer*65536/1;
}

두 글자씩 끊어서 다중집합을 만드는 함수를 만들었다.

find, erase함수를 사용하여 합집합, 교집합의 개수를 구하였다.

 

 

append

문자열 끝에 문자들을 붙이는 함수이다.

 

함수 원형

append(const string&str, size_type str_idx, size_type str_num)
  • str : 추가할 문자열
  • str_idx : 추가할 문자열의 시작 지점
  • str_num : 시작 지점으로부터 몇 개의 글자를 추가할 것인지
append(size_type num, char c)
  • c 문자열을 num개만큼 반복해서 붙인다.

 

 

 


다른 사람 풀이 1

#include <bits/stdc++.h>
using namespace std;
short a, b, C[676], D[676];
int solution(string A, string B) {
    for(int i=1; i<A.size(); i++)
        if(isalpha(A[i-1]) && isalpha(A[i]))
            C[(A[i-1]&31)*26+(A[i]&31)]++;
    for(int i=1; i<B.size(); i++)
        if(isalpha(B[i-1]) && isalpha(B[i]))
            D[(B[i-1]&31)*26+(B[i]&31)]++;
    for(int i=0; i<676; i++) a+=min(C[i], D[i]), b+=max(C[i], D[i]);
    return b ? a*65536/b : 65536;
}

 

다른 사람 풀이 2

#include <string>
#include <vector>
#include <algorithm>
#include <cctype>

using namespace std;

int solution(string str1, string str2) {
    vector<int> multiset1 = vector<int>(676, 0);
    vector<int> multiset2 = vector<int>(676, 0);

    transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
    transform(str2.begin(), str2.end(), str2.begin(), ::tolower);

    for (int i = 0; i < str1.length() - 1; i++) {
        char first = str1[i];
        char second = str1[i+1];

        if (first >= 97 && first <= 122 && second >= 97 && second <= 122 ) {
            multiset1[(first-97)*26 + (second-97)]++;
        }
    }

    for (int i = 0; i < str2.length() - 1; i++) {
        char first = str2[i];
        char second = str2[i+1];

        if (first >= 97 && first <= 122 && second >= 97 && second <= 122 ) {
            multiset2[(first-97)*26 + (second-97)]++;
        }
    }

    int numberOfIntersection = 0;
    int numberOfUnion = 0;

    for (int i = 0; i < 676; i++) {
        numberOfUnion += max(multiset1[i], multiset2[i]);
        numberOfIntersection += min(multiset1[i], multiset2[i]);
    }

    if(numberOfUnion == 0)
        return 65536;
    else
        return (int)(((double) numberOfIntersection / (double) numberOfUnion) * (double) 65536);
}

 

두 풀이 모두 알파벳 두 개를 인덱스로 만드는 방법을 사용했다.

*26을 해준 이유는 알파벳 개수가(소문자만) 26개이고, ab와 ba의 경우 인덱스를 다르게 주기 위함이다.

-97을 해 준 이유는 아스키코드표에 97이 'a'에 해당하기 때문이다

 

transform

<algorithm>에 정의되어있다.

특정 함수를 써서 값을 변경해야 할 때 유용한 함수이다.

 

함수 원형

transform(InputIt first 1, InputIt last 1, OutputIt d_first, UnaryOperation unary_op);
  • first 1, last 1 : transform 함수를 적용할 원소들을 가리키는 범위
  • d_first : 결과를 저장할 범위. (first 1과 동일할 경우 기존 데이터를 덮어쓰게 된다.)
  • unary_op : 원소들을 변환할 함수
transform(str.begin(), str.end(), str.begin(), ::tolower);
  • 위의 코드로 str의 모든 문자를 소문자로 만들 수 있다.

 

 

isalpha

알파벳을 확인하는 함수.

알파벳일 경우 0이 아닌 수를 반환하고, 알파벳이 아닐 경우 0을 반환한다.

isalpha (int c);

isalpha 함수의 매개변수로

  • 아스키코드표에 'A-Z'에 해당하는 65번~90번의 값이 들어오면 1을 반환한다.
  • 아스키코드표에 'a-z'에 해당하는 97번~122번의 값이 들어오면 2를 반환한다.
  • 알파벳이 아닌 것은 0을 반환한다.

 

 


https://jhnyang.tistory.com/115

 

[C++]string 라이브러리 사용법 1탄, 비교(compare),추가(append),찾기(find),크기(size,length)등 함수(메서드)

[C언어, C++언어, 자바 언어 프로그래밍 강좌 목차] [C++] String Library 알아보기~~!! 1탄입니다. ㅎㅎ String은 문자열을 나타내기 위한 클래스입니다. 문자를 조작하는 일은 정말정말 많이 쓰이죠 ㅎㅎ

jhnyang.tistory.com

https://artist-developer.tistory.com/28

 

[C++] transform 함수

안녕하세요. 개발자 김모씨입니다. C, C++ 탭을 새로 만들었습니다~~~~~~ 여기에는 실무에서 주로 사용되는 함수들, 또는 코딩테스트에서 사용하면 편리한 함수들을 간단하고 가볍게 공유할 거에

artist-developer.tistory.com

https://blockdmask.tistory.com/448

 

[C언어/C++] isalpha 함수 (알파벳을 확인하는 함수)

안녕하세요. BlockDMask 입니다. 오늘은 C언어 C++에서 알파벳인지 확인할 수 있는 isalpha 함수에 대해 알아보려합니다. 예전에 문자가 숫자인지 확인해주는 isdigit() 함수를 소개해드린적이 있는데요.

blockdmask.tistory.com