꽤나 골칫거리였던 문자열을 리뷰해보고, 객체지향 언어인 C++에서 문자열을 처리하는 방식에 대해서 정리해본다.
최근에 집에서 할 것이 없어서 백준에서 인하대학교 프로그래밍 경시대회 문제들을 풀어봤는데 문자열 처리에 있어서 도움이 될만한 문항이 있어 이를 공유하고자 한다.
#include <iostream>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
기본적으로 알고리즘 문제들을 해결하기 위해서 위와 같은 다양한 STL을 호출한 상태로 코딩한다.
처음에 프로그래밍을 공부할 때 고민이었던 것이 하나 있었는데 그것은 바로 '저렇게 많은 STL들이 있고, 그들이 각각 제공하는 수많은 내장함수들이 존재하는데 그것들 모두를 인지한 채로 다음 단계로 넘어가야하는것인가?'였다.
주변 지인들에게 물어보며, 독학하면서 내린 결론은 '필요할 때 마다 찾아가면서 익숙해지자'였다.
왜 여기서 갑자기 이 이야기를 하냐 하면 문자열을 비롯해서 스택, 큐, 벡터 등의 다양한 STL들을 앞으로 활용하게 될텐데 각각에서 제공하는 내장함수들을 모두 기억하고 사용하는 것은 말이 안된다. 몇몇 자주 사용하는 함수들이 있고, 그것들 위주로 문제들을 해결해나가고 다른 사람들의 코드를 살펴보면서 효율적이라는 판단이 서면, 혹은 필요하다는 생각이 들 때면 사용해보면 될 듯하다.
이번 포스팅에서는 이거는 무조건 알아야한다는 수준의 함수들과 문자열 처리에 대해서 소개하고, 추가적인 정보들을 Reference들의 링크를 걸어둘테니 한 번씩 구경하길 바란다.
1) 문자열 선언 방식
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char word[] = "Hello";
char* word2 = "Hello";
return 0;
}
C에서는 문자열 처리 라이브러리인 string.h와 문자 처리 라이브러리 ctype.h를 Include한 채로 문자열 처리를 진행해왔다.
위에서는 C에서 문자열을 표현하는 2가지 방식을 보여주는데 문자들로 이루어진 배열로 선언한 word와 포인터를 활용하여 문자열의 첫번째 주소를 가리키는 word2가 선언되어 있다. (굳이 포인터보다는 첫번째 방식을 선호함)
중요한 점은 C언어에서는 문자열을 null로 종료된 문자 배열로 표현한다는 점이다.
예를 들어 word의 구성을 살펴보면 {'H', 'e', 'l', 'l', 'o', '\0'}로 표현된다. null 문자('\0')는 문자열의 끝을 나타내는 특수한 문자이다.
2) 사용자로부터 문자열 입력 받는 방식
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char word[100];
char word2[100];
//공백 없이 입력 받는 경우 -> scanf사용
scanf("%s",word);
printf("%s\n",word);
//공백을 포함하여 입력 받는 경우 ->gets 사용
gets(word2);
printf("%s",word2);
return 0;
}
코드에 주석으로 적힌 그대로다.
문자열 관련 알고리즘 문제들을 마주하면 세상에 남자와 여자가 있듯이,
문자열에 공백이 있거나 없을 것이다.
이 방식을 벗어나서 사용자로부터 입력을 받을리는 없으니 기억하도록 한다.
3) 문자열 관련 다양한 함수들
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char word[100];
gets(word);
printf("%d",strlen(word));
return 0;
}
매우 자주 사용하기에 반드시 인지하고 있어야 하는 함수로는 strlen을 뽑는다. 입력받은 문자열이 공백이 있거나 없거나 그 길이를 알려주는 함수이다.
문자열을 첫 문자부터 끝까지 검사해야 할 때가 많은데 이 경우에 제한범위로 strlen을 활용해서 저장해둔 문자열의 길이를 사용하면 된다.
이 함수 이외에 유용한 문자열 라이브러리 함수들은 다음 Reference로 한 번 정도씩 봐두도록 하자. (사실, strlen말고는 잘 사용하지 않기는 함)
http://www.tcpschool.com/c/c_string_handling
문자열/문자 관련 함수들 정리 자료
1) 문자열 선언 방식
#include <iostream>
#include <string>
using namespace std;
int main() {
string word;
word = "Hello";
cout << word << endl;
return 0;
}
말이 안되게 편리하다.
정수형 int 선언하듯이 string이라는 STL을 호출한 이후에는 string 즉, 문자열을 하나의 자료형이라고 생각하고 자유롭게 처리해주면 된다.
2) 사용자로부터 문자열 입력 받는 방식
#include <iostream>
#include <string>
using namespace std;
int main() {
string first;
string second;
// 사용자로부터 공백이 없이 입력받는 경우
cin >> first;
// 사용자로부터 공백이 있이 입력받는 경우
getline(cin,second);
cout << first << second << endl;
return 0;
}
C++이라고 cin을 통해서 공백이 포함된 문자열이 저장되지는 않는다.
함수 명칭만 달라졌을 뿐 C에서와 방식은 비슷하다.
getline함수 정도는 자주 사용하니 알아두도록 한다.
3) 문자열 관련 다양한 함수들
#include <iostream>
#include <string>
using namespace std;
int main() {
string word;
cin >> word;
//strlen 대신에 size함수 사용 크기? 매우 직관적
cout << word.size() << endl;
return 0;
}
C에서와 마찬가지로 문자열의 크기를 보여주는 함수로 Size가 있고, 매우 자주 사용하니 인지하도록 하자.
주의 깊게 볼 만한 포인트가 하나 있는데 C에서와 C++에서의 함수 사용 방식에 있어서 차이를 살펴보도록 하자. C에서는 Strlen(word)로 표현이 되고, C++에서는 word.size()로 표현이 되는데 이는 객체지향의 개념과 연관이 되어있다. C는 절차 지향이기에 절차인 strlen을 먼저, 객체인 word가 뒤에 나오고 있고, C++은 객체 지향이기에 객체인 word에 대하여 size라는 동작을 선언해주고 있다. word.size()와 같은 방식으로 앞으로 대부분의 함수들을 사용하게 되니 익숙해지도록 하자.
마찬가지로 size함수를 제외하고도 쓸만한 함수들 다수를 제공해주고 있는데 아래 Reference를 통해서 한 번쯤 봐두자. (사실 잘 안 씀)
https://rebro.kr/53
C++ 문자열 처리 관련 자료
위에서 언급한 문자열 연습하기에 좋은 문제 하나가 있어서 소개한다.
아래 문제를 차분하게 읽어보고 해결해보자.
https://www.acmicpc.net/problem/28074
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
#include <string>
using namespace std;
void test() {
string word;
cin >> word;
int len;
len = word.size();
string cmp;
cmp = "MOBIS";
int temp = 0;
for (int i = 0; i < cmp.size(); i++)
{
for (int j = 0; j < len; j++)
{
if (cmp[i] == word[j])
{
temp += 1;
break;
}
}
}
if (temp == 5)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
int main() {
test();
return 0;
}
풀이 방법은 매우 다양할텐데, MOBIS라는 비교대상인 문자열 하나를 설정해두고 M부터 S까지를 이중 반복문을 활용하여 있는지 조사하고, 있다면 임의의 값에 추가해주는 방식으로 구현했다.
만약에 M부터 S까지가 있기만하면 발문에 따라 "YES"를 외칠 수 있으니 temp라는 값이 5면 YES를 5가 아니면 NO를 출력해준다.