문제풀이(Problem Solving)/C++ 문제풀이에 유용한 것들

C++에서 Python Split과 같은 함수 만들기

게임이 더 좋아 2022. 2. 3. 16:17
반응형
728x170

 

우선 Python 에서의 split 함수를 보자

2개의 인자를 받는다

1. delimiter, 구분자

2. 해당 문자열

 

알아봤다면 시작해보자

 


 

그렇다면 우리는 우선 가장 흔한 공백을 기준으로 만들어보자

 

막연하게 드는 생각은

공백을 만나면 공백을 만나기 전까지의 모든 문자열을 어떠한 컨테이너에 넣고

문자열을 다시 진행하면 될 것 같다.

 

즉, 문자열을 하나하나 조사한다는 말이다.

공백을 만나면 그때까지의 문자열을 다시 집어넣고

다시 공백이 나오지 않을 때까지 탐색한 후 다시 반복한다.

만약 문자열이 끝나면 끝나게 된다.

 

대충 이런 생각으로 짠다.

위에서 아이디어를 뽑아보자면

 

1. 문자열을 하나하나 조사할 것임

2. 공백만났을 때 하는 행동

3. 문자열의 끝에 닿았을 때 하는 행동

 

C++에서 알다시피 문자열은 임의 접근이 가능하다.

배열처럼 접근이 가능하다.

iterator를 쓰는 것보다 인덱스로 접근하는 것이 더 직관적일 것 같다.

한 번 만들어보자

 

vector <string> split(const string& target){

    vector<string> ret; //나누어진 문자열들을 담을 벡터
    typedef string::size_type string_size; //이건 그냥 string 클래스의 멤버다.
    
    string_size i = 0;
    
    //문자열 하나하나 조사해야함
    while(i != target.size()){
        
        //공백이라면 다음 문자열 조사.
        while(i != s.size() && isspace(target[i]))
            i++;
            
        //공백이 아니라면 그 단어의 시작점을 i라고 본다.
        //j로 해당 단어를 조사한다. (끝점이 어디인지)
        string_size j = i;
        
        //j 자체도 공백이 나올때까지 진행한다.
        while(j != target.size() && !isspace(target[j]))
            j++;
        
        //j가 공백까지 진행되었다면 j는 공백의 위치에 있으면서 j 바로 앞에는 단어의 끝 점이 놓여있을 것이다.
        if(i != j){
            //i가 시작점 j-1이 끝점이다.
            //즉, i를 포함해서 j-i 글자를 취하면 된다.
            ret.push_back(target.substr(i, j-i));
            i=j; // i를 다시 공백에 위치해서 시작하게 만듬.
        }
    }
    
    
    //다만 모든 while에서 인덱스가 벗어나지 못하도록 size 비교를 해주어야 한다.
    
    return ret;
    
    



}

 

이건 공백이고..

그렇다면 우리가 구분자를 받고 싶다면 어떻게 해야할까??

쉽다.

저기 isspace부분을 바꿔주면 된다.

vector <string> split(const string& target, char delimiter){

    vector<string> ret; //나누어진 문자열들을 담을 벡터
    typedef string::size_type string_size; //이건 그냥 string 클래스의 멤버다.
    
    string_size i = 0;
    
    //문자열 하나하나 조사해야함
    while(i != target.size()){
        
        //delimiter이라면 다음 문자열 조사.
        while(i != s.size() && target[i] == delimiter)
            i++;
            
        //공백이 아니라면 그 단어의 시작점을 i라고 본다.
        //j로 해당 단어를 조사한다. (끝점이 어디인지)
        string_size j = i;
        
        //j 자체도 공백이 나올때까지 진행한다.
        while(j != target.size() && !target[j] == delimiter))
            j++;
        
        //j가 공백까지 진행되었다면 j는 공백의 위치에 있으면서 j 바로 앞에는 단어의 끝 점이 놓여있을 것이다.
        if(i != j){
            //i가 시작점 j-1이 끝점이다.
            //즉, i를 포함해서 j-i 글자를 취하면 된다.
            ret.push_back(target.substr(i, j-i));
            i=j; // i를 다시 공백에 위치해서 시작하게 만듬.
        }
    }
    
    
    //다만 모든 while에서 인덱스가 벗어나지 못하도록 size 비교를 해주어야 한다.
    
    return ret;
    
    



}

 

 

여기서 필요한 표준 헤더들은

<string>

<cctype> 정도 되겠다.

 

반응형
그리드형