프로그래머스 문제 풀다가 , 문자열 처리에서 꽤 난감했었다.
C++를 좋아하지만 문자열 처리가 편리하지만은 않은데 한번 C++로 문자열을 다루는 방법을 짚고 넘어가보자
C++쓰면서 string만 잘 사용해도 , 꽤나 문자열 처리가 편리해진다.
기존 C에서는 1바이트 Char자료형을 배열로서 문자열을 사용할 수 있지만 string 클래스를 통해서 굉장히 편리하게 문자열을 다룰 수 있다.
일단 기본적으로 string클래스는 내부적으로 1바이트 char를 담아두고 있다.
해당 1바이트 char를 담아두기 위한 컨테이너로 vector를 사용하고 있는데 , 덕분에 vector에서 사용하는 메소드들은 string에서도 사용가능하다.
python같은 경우는 split과 같은 메소드로 쉽게 특정 delim을 기준으로 토크나이징이 가능하지만 , 근본 C++는 역시 근본 언어답게 그런 편리한 기능따위는 존재하지 않는다.
하지만 , stringstream 클래스를 사용하면 그나마 쉽게 토크나이징이 가능한데
#include <sstream>
#include <string>
using namespace std;
int main(int argc,int *argv[])
{
/* 문자열을 ',' 단위로 토큰화하고 싶은 경우 */
string target_string = "I,MY,ME,MINE";
stringstream sstream(target_string);
vector<string> words;
string word;
while(getline(sstream,word,',')
words.push_back(word);
for(auto word : words)
cout<<word<<" ";
/* I MY ME MINE */
우선 토크나이징 하고자하는 문자열을 stringstream의 생성자의 인수로 넣어주면 , 해당 문자열의 stream 객체가 생성된다. 이후 getline을 통해서 세 번째 인수를 기반으로 토크나이징을 할 수 있다. 이 방법이 그나마 편리한 방법인것 같다.
사실 저게 끝이면 , 문자열처리가 까다롭다고도 말 안할것이다.
보통 코딩테스트문제는 문자열을 토큰화하여 비교연산하는 일들이 많이 발생한다.
문자열 A,B가 주어집니다.
문자열은 "A","B","C","C#","D","D#" 으로만 이루어져 있습니다.
A = "ABC#D#D" ;
B = "AGC#D#D#" ;
B 안에 A가 포함되어 있을까요?
위의 예시에서 , 단순히 B.find(A)를 돌려버리면 B안에 A가 포함되어있다고 나올 것이다. 근데 두 문자열의 끝이 "D" 하고 "D#"으로 다르므로 사실 포함되어있지 않다.
위와 같은 상황을 방지하기위해서는 , vector같은 컨테이너를 하나 선언하고 ( 굳이 vector가 아니어도 되지만 편리하다) 위의 문자열 A와 B를 atomic한 단위로 토큰화하여 vector에 넣고 이후에 비교하는 것을 추천한다.
사실, 그냥 python 사용하자 진짜 훨씬 편하긴 하다..