Coding Interview/빈출유형 정리

[C++] 코딩 테스트 대비 문자열 처리 함수 정리

2로 접어듦 2022. 12. 23. 19:33

 문자열 입력 받기 

getline

입력 문자열이 스페이스 바 혹은 '\n' 이 있는 문자열일 경우, cin >> string 으로는 처리하기 힘들다. getline으로 처리할 경우 손쉽게 처리할 수 있다.

  • cin의 getline 이 있고, string의 getline이 있다. 나는 string 의 getline 이 편했다.
  • 입력받는 문자열에 대해 deliminator 전까지를 하나의 string으로 처리해준다.
  • getline(istream& is, string str);
    getline(istream& is, string str, char dlim);
  • 보통 istream으로는 cin 을 쓰고, 저장하고자 하는 변수 str를 지정해주면 된다.

주의사항

이전 입력에서 '\n'이 처리되지 않았을 경우(buffer에 남은 경우) getline이 제대로 작동하지 않을 수 있다. 이 경우를 대비하여, getline 실행 전 cin.ignore()를 선언해줌으로써 버퍼에 남은 '\n'을 제거할 수 있다.

 

for(int i=0; i<N; i++){
    string str;
    getline(cin, str);
    cout << str << endl;
}

 

관련 문제

  1. https://www.acmicpc.net/problem/1718

 

sstream

입력 문자열에 문자, 정수형 등이 섞여 있는 형태에서 문자열과 정수형을 구분하는 데에 많이 사용된다.

 

주의사항

  1. '문자' 와 '정수'를 구분하는 것이므로, string 이 아닌 char와 int로 써야 한다는 것에 주의해야 한다.
  2. while 문을 사용하기 때문에, 마지막 문자/정수가 저장되지 않을 수 있다. 입력 문자열이 남아있을 동안만 while문이 동작하므로, 마지막 input 소실에 유의해야 한다.
// 백준 1541 풀이 중 일부
#include <sstream>

/*	인풋 처리	*/
//input 예시: 55-50+40
stringstream ss(input);
int num;
char op;
while(ss >> num >> op){
    number.push_back(num);
    oper.push_back(op);
}
number.push_back(num);	// int형 변수num이 마지막에 push 되지 않고 종료된다.

 

관련 문제

  1. https://www.acmicpc.net/problem/1541
  2. https://school.programmers.co.kr/learn/courses/30/lessons/42888

 

sstream 과 getline 사용 구분 요약

입력이 한 줄이되, 띄어쓰기로 구분되어있는 경우 sstream 을 이용하는 것이 편리하며,

입력이 \n 으로 구분되어있는 경우는 getline을 사용하는 것이 편리하다.


문자열 처리하기

코딩테스트 문제풀이에 상당히 자주 사용되는 c++ 문자열 처리 함수를 보기 좋게 정리해두고자 한다.

목록: to_lower, compare, to_string, stoi, append, string::push_back, string::erase

 

find

substr

 

tolower && toupper

문자열을 비교할 때, 대소문자 구별없이 비교해야할 경우가 종종 있다.

이 함수는 '문자 하나'를 소문자로/대문자로 변환시켜주는 함수이다. 그래서 보통 문자열 전체를 변환하고자 할 때는 transform 함수와 함께 사용한다.

char tr(char ch){
    return tolower(ch);
}

string str_tolower(string s){
    transform(s.begin(), s.end(), s.begin(), tr);	// 함수 파라미터가 특이하다.
    return s;
}

string head = "Test STRING";
string head_transformed = str_tolower(head);	// test string이라는 값으로 초기화된다.

 

compare

string 끼리의 compare 연산이 가능하며, 문자열들을 '사전순으로' 정렬하고자 할 때 sort알고리즘과 함께 많이 사용된다.

string A.compare(B)의 형태로 사용하며, string A 가 B보다 사전순으로 앞서다면 0보다 작은 음수 값이 리턴되며, 같으면 0이 리턴된다. 아마, 대소문자도 구분해서 리턴하는 것으로 알고 있다.(대문자가 사전순에서 더 뒤였던 듯)

int compare(const basic_string& str) const;

string str1, str2;
str1.compare(str2); // return - or 0 or +

// sort에서 사용할 때
bool comp(string str1, string str2){
    return (str1.compare(str2) < 0) ? true:false // 사전순으로 정렬하고 싶을 때. 추가적으로 '같은'경우에 대한 정렬기준이 필요함.
}
...
stable_sort(vector<string> vv.begin(), vv.end(), comp);

 

to_string

정수형 변수를 string으로 변환하고자 할 때 많이 사용된다.

정수를 문자형태로 만든 뒤, 다른 문자열에 append 하면서 많이 활용된다.

std::string to_string( int value );

 

stoi && stol && stoll

문자열 형태로 입력된 정수형을 integer 형태로 변환시켜주는 편리한 함수이다.

문자열에서 정수를 뽑아내는 과정에서 sstream이 아닌 인덱싱 방법을 사용했다면, 문자 하나하나를 integer str +=something[i]로 만들었을 것이고, 이 str 은 추후 stoi(str)을 통해 int 형태로 변환할 수 있다.

(인덱싱 방법을 쓴 이유는 sstream 사용이 상당히 까다로울 수 있겠다 싶어서였다. 문자열을 head, body, tail 로 나누어서, 정수형이후의 문자열은 처리하지 않는다던가... 등등)

 

주의사항

문제에 따라 리턴해야 하는 수가 long long이어야 하는 경우가 있다. 이 경우 stoll을 사용함에 주의해야 한다.

std::strtol(str.c_str(), &ptr, base)
std::strtol(str.c_str(), &ptr, base)
std::strtoll(str.c_str(), &ptr, base)

// 그냥 보통 stoi(string)의 형태로 사용한다

 

관련문제

https://school.programmers.co.kr/learn/courses/30/lessons/17686

 

append

문자열과 문자열을 합치고 싶을 때 사용한다. 특정 문자를 반복해서 여러번 합치고 싶은 경우에도 이 함수를 사용할 수 있으나, 아직 활용하는 경우를 보진 못했다. 참고: https://devdocs.programmers.co.kr/cpp/string/basic_string/append

string answer = "answer";
string str = "go go";
answer.append(str); // return answergo go

 

std::basic_string::push_back &

std::basic_string::pop_back

주어진 문자열에 특정 문자를 반복적으로 더해야 하는 경우 사용할 수 있다.

push_back의 경우, 문자열에 특정 "문자(Character)"만이 추가 가능하다. String도 하나의 벡터와 같다고 생각하면 편하지만, 그렇다고 string.push_back(string)이 되는 것은 아니기에, character만 가능함에 꼭 유의해야 한다.

함수의 기본 형태는 아래와 같다.

void push_back( CharT ch );
void pop_back();

string.push_back(ch);

 

참고

문자열에는 string += char 연산도 가능하다. 본인은 그래서 아래와 같은 방식을 쓰는 게 편했다.

string answer = "";
...
	answer += something[i];
...
return answer;

 

std::basic_string::erase

string push_back과 마찬가지로 string의 특정 문자 혹은 특정 문자열을 지우고 싶은 경우가 있다. find를 사용하는 것이 아니므로, erase하고자 하는 문자 혹은 문자열의 위치 idx를 알고 있어야 사용가능하다.

첫 번째 파라미터는 erase의 시작위치, 두 번째 파라미터는 시작위치로부터 몇 개를 지울지를 결정하는 파라미터다.

iterater로도 erase가 가능하다.

basic_string& erase( size_type index = 0, size_type count = npos );
iterator erase( iterator position );

images.unsplash.com/photo

 

관련 문제

  1. https://school.programmers.co.kr/learn/courses/30/lessons/17684
  2. https://school.programmers.co.kr/learn/courses/30/lessons/64065
  3. https://school.programmers.co.kr/learn/courses/30/lessons/17686

 

참고한 사이트

  1. https://ronick-grammer.github.io/
  2. https://prod.velog.io/
  3. https://kyu9341.github.io/
  4. https://devdocs.programmers.co.kr/cpp/