[자료구조와 알고리즘] String
String
string은 클래스입니다.
string은 클래스이므로 객체를 생성할 수 있습니다.
#include <iostream>
#include <string>
using namespace std;
int main()
{
// 객체 생성
string s1; // string객체 s1 생성
// 객체 초기화
string s2 = "Hello World"; // string객체 s2 생성후 초기화
string s3 {"Hello World"}; // string객체 s3 생성후 초기화
}
다음과 같이 객체 생성과 초기화를 할 수 있습니다.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string list[] = { "SUSOT", "Game", "Data" };
for (auto a : list)
{
cout << a << endl;
}
}
String배열과 foreach와 auto
string도 다음과 같이 배열로 만들 수 있습니다.
저 for문은 c# foreach처럼 배열요소에 각각 접근하여 하나씩 출력해줄 수 있다. 이때 auto는 자동형식추론 변수로
저기서 auto는 자동으로 string을 받습니다.

getline()
만약 string에 공백을 포함하여 입력을 받고싶다면 getline을 사용하면 됩니다.
대신 getline을 쓰려면 #include <string>를 써줘야합니다.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
getline(cin, s);
cout << "지금 쓴 텍스트 : " << s;
}

대신 getline을 쓸때는 주의사항이 있습니다.
cin입력을 받은 뒤 getline을 받는다면
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1;
string s2;
cin >> s1;
cout << "지금 쓴 텍스트 : " << s1;
getline(cin, s2);
cout << "지금 쓴 텍스트 : " << s2;
}

안녕하세요만 입력하였지만 코드가 종료되는걸 볼 수 있습니다.
이는 cin입력을 받고 ENTER를 칠때 입력 버퍼에 '\n'이 남게되는데 cin은 입력버퍼에 \n'를 무시하지만
getline은 이를 포함해서 입력받기 때문에 바로 ENTER를 친걸로 인식해버립니다.
따라서 입력버퍼를 비워줄 필요가 있습니다.
입력버퍼를 비울떄는 cin.ignore()를 사용하면 됩니다.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1;
string s2;
cin >> s1;
cout << "지금 쓴 텍스트 : " << s1 << endl;
cin.ignore();
getline(cin, s2);
cout << "지금 쓴 텍스트 : " << s2;
}

이제 잘 작동되는것을 볼 수 있습니다.
String 클래서 맴버 함수
string 클래스에는 여러 맴버 함수가 있습니다.
문제를 풀면서 맴버변수를 써보겠습니다.
1. 문자열 "When in Rome, do as the Romans."중에서 "Rome"이 몇 번째 위치에 있는지를 계산하는 프로그램을 작성해보자.
int main()
{
string s = "When in Rome, do as the Romans.";
cout << s.find("Rome");
}
string.find는 매개변수로 받은 문자열이 처음 나오는 인덱스 값을 반환하는 함수입니다.
따라서 Rome에 첫 인덱스값인 8이 반환됩니다.

2. 사용자가 입력한 주민등록번호에서 ‘-’ 문자를 삭제하는 프로그램을 작성하여 보자.
int main()
{
string s;
cout << "주민등록번호를 입력하시오 : ";
cin >> s;
cout << s.erase(s.find("-"), 1);
}
string.erase는 처음 입력받은 인덱스부터 뒤에 값을 지우는 함수입니다. 여기서는 s.find("-")를 해주었기 때문에 -가 있는 인덱스값부터 지우게 됩니다.
하지만 -만 지우고 뒤에 값은 유지해야 하기 때문에 추가로 1을 입력하여 한글자만 지우게 하였습니다. 1을 지울 글자수를 뜻합니다.

3. 유전자를 나타내는 2개의 문자열을 받아서 동일한 위치에 틀린 글자가 몇개나 있는지를 계산하는
프로그램을 작성해보자. 이것을 해밍 거리(Hamming distance)라고 한다.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1;
string s2;
int cnt = 0;
cin >> s1;
cin >> s2;
for (int i = 0; i < s1.size(); i++) // s1.length();도 가능
{
if (s1[i] != s2[i])
{
cnt++;
}
}
cout << cnt;
}
string.size(= string.length)는 string배열의 크기를 반환합니다.
이를 이용하여 같은 인덱스에서 값이 같은지 다른지를 비교할 수 있습니다.

4. 입력받은 문자열에서 o를 x로 바꾸는 함수를 작성해보자.
int main()
{
string s;
cin >> s;
for (int i = 0; i < s.length(); i++)
{
if (s[i] == 'o')
{
s.erase(i, 1);
s.insert(i, "x");
}
}
cout << s;
}
string.insert는 두개의 매개변수 (자리, 넣을 값)을 받습니다.
지금은 i번째 자리가 o이면 o를 지우고 그 자리에 x를 넣는 코드입니다.

5. 빈칸을 포함하는 문자열을 입력받은뒤 문자열 위치 바꾸기
int main()
{
string s;
cout << "빈칸을 포함하는 문자열을 입력하세요." << endl;
getline(cin, s);
for (int i = 0; i < s.length(); i++)
{
char c;
c = s[0];
s.erase(0, 1);
s.push_back(c);
cout << s << endl;
}
}
string.push_back()은 string에 맨 뒷자리에 문자 하나를 추가하는 함수입니다.
이를 이용하여 맨 앞자리 문자를 c에 저장한뒤 지우고, push_back을 이용하여 뒤에 넣어주면 됩니다.

이 외에도 더 많은 맴버 함수가 있습니다.


오늘은 string에 대해 알아보았습니다.
