2023. 8. 21. 17:46ㆍ프로그래밍 언어/C++\C
코테를 준비하거나 대회를 준비하면 문자열에 절대 겁먹어선 안된다. 기초부터 꼭 알아야 할 메서드들까지 공부해 보자!
C++에서의 문자열 관리법
1. string 클래스
string은 C++ 표준 라이브러리 클래스로 문자열을 동적으로 할당하고 관리한다. 내부적으로 동적 할당된 배열을 사용하여 문자열 데이터를 저장하며, 문자열의 길이도 함께 저장한다.
2. 동적 할당
문자열 길이에 따라 필요한 만큼의 메모리를 동적으로 할당한다. 이로 인해 문자열의 크기를 런타임에 조절한다.
3. 메모리 구조
Null-Terminated Strings
문자열을 null-terminated 형식으로 표현하는데, 문자열의 끝에 자동으로 null문자를 추가하여 문자열의 끝을 표시한다.
5. 메모리 관리
문자열 객체가 생성될 때 관련 메모리가 할당되며, 객체가 파괴될 때 메모리가 자동으로 해제된다. 내부적으로 문자열 길이에 따라 메모리를 확장하거나 축소할 수 있다.
기본 메서드
1. 문자열 선언과 초기화
string str = "Hello";
string str2 = "World";
cout << str + str2; //Hello World
2. 문자열의 길이
str.length();
str.size();
3. 문자에 접근
char firstChar = str[0];
char lastChar = str.back();
4. 문자열 비교
string str1 = "a";
string str2 = "b";
str.compare(str2);
//같으면 0 리턴, 다르다면 첫 번째 문자열이 두 번째 문자열보다 사전적으로 작으면 음수를 아니라면 양수를 반환한다.
5. 문자열 추출
string str = "Hello World";
string sub = str.substr(6, 5); //"World"
//str[6]부터 size5만큼 자른다. endIndex를 지정하여 자르지는 못하므로 길이를 계산해서 잘라야 한다.
//endIndex - startIndex + 1로 길이를 계산할 수 있다.
6. 특정 문자 찾기
string str = "Hello World";
int found = str.find("World);
//World가 처음 등장하는 index를 알려준다. 만약 없다면 nops를 반환한다. nops는 string에서 유효하지 않은 위치이다.
7. 문자열 수정
string str = "Hello";
str.insert(2, "XYZ"); //2번 index에 "XYZ"를 삽입한다. 결과는 "HeXYZllo"가 된다.
str.erase(1, 2); //1번 index부터 2 길이만큼 삭제한다. 결과는 "HYZllo"가 된다.
str.replace(1, 2, "ABC"); //1번 index부터 2 길이만큼 "ABC"로 대체한다. 결과는 "HABCllo"가 된다.
8. 문자열 변환
string str = to_string(42); //정수 42를 문자열로 변환할 수 있다.
int num = stoi("123") //문자열 "123"을 정수 123으로 변환할 수 있다.
double decimal = stod("3.14") //"3.14"를 3.14로 변환할 수 있다.
9. 문자열 대문자, 소문자 변환
<algorithm> 라이브러리의 transform() 함수는 두 개의 범위를 받아와서 각 요소를 변환하여 다른 범위에 저장하는 역할을 한다. 주로 컨테이너의 모든 요소를 일괄적으로 변환하는 데 사용된다. 매개 변수는 차례로 변환을 수행할 원본 컨테이너의 시작과 끝 반복자, 변환된 결과를 적용할 시작 반복자, 각 요소에 적용할 변환 함수이다.
예를 들어 모든 문자를 대문자로 변환하려면 toupper()를 함께 사용할 수 있다. 소문자는 tolower()이다.
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string str = "Hello, World!";
// 모든 문자를 대문자로 변환
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
std::cout << str << std::endl; // "HELLO, WORLD!"
return 0;
}
대소문자 상호 변환도 비슷한 방식으로 구현할 수 있다.
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string str = "Hello, World!";
// 대문자를 소문자로, 소문자를 대문자로 변환
for (char& c : str) {
if (std::isupper(c)) {
c = std::tolower(c);
} else if (std::islower(c)) {
c = std::toupper(c);
}
}
std::cout << str << std::endl; // "hELLO, wORLD!"
return 0;
}
문제풀이에서 많이 쓰이는 문자열 활용법
1. 문자열 역순
string str = "Hello";
reverse(str.begin(), str.end());
2. 문자열 정렬
string str = "hello";
sort(str.begin(), str.end()); //sort() 함수는 algorithm 라이브러리에 있다.
3. 문자열 초기화
string str = "string";
str.clear();
4. 문자열을 특정 문자 기준으로 자르기.
find() 함수와 substr() 함수를 활용하면 된다.
#include <iostream>
#include <string>
int main() {
std::string input = "apple,banana,cherry,grape";
std::string delimiter = ",";
int pos = 0; // 위치 변수
std::string token;
while ((pos = input.find(delimiter)) != std::string::npos) {
token = input.substr(0, pos); // delimiter 위치까지의 부분 문자열 추출
std::cout << token << std::endl; // 추출된 부분 문자열 출력
input.erase(0, pos + delimiter.length()); // 추출한 부분 문자열 삭제
}
// 마지막 남은 부분 문자열 출력
if (!input.empty()) {
std::cout << input << std::endl;
}
return 0;
}
5. 찾은 문자열의 위치부터 해당 문자열의 길이까지 추출하기
#include <iostream>
#include <string>
int main() {
std::string str = "Hello, World!";
std::string target = "World";
size_t found = str.find(target);
if (found != std::string::npos) {
std::string foundSubstring = str.substr(found, target.length());
std::cout << "Found substring: " << foundSubstring << std::endl;
} else {
std::cout << "Not found" << std::endl;
}
return 0;
}
6. 문자열 압축
"aaabbbcccccddd"를 압축하면 "a3 b3 c5 d3"으로 출력되게 구현하였다.
#include <iostream>
#include <string>
// 문자열을 압축하는 함수
std::string compressString(const std::string& str) {
std::string compressed; // 압축된 문자열을 저장할 변수
char prevChar = str[0]; // 이전 문자 초기화
int count = 1; // 현재 문자가 연속해서 나온 횟수 초기화
// 문자열을 탐색하며 압축 수행
for (size_t i = 1; i < str.length(); ++i) {
if (str[i] == prevChar) {
count++; // 현재 문자가 이전 문자와 같으면 카운트 증가
} else {
// 현재 문자가 이전 문자와 다르면 압축된 문자열에 추가
compressed += prevChar + std::to_string(count);
prevChar = str[i]; // 이전 문자 갱신
count = 1; // 카운트 초기화
}
}
// 마지막 문자 처리
compressed += prevChar + std::to_string(count);
// 압축 결과가 원래 문자열보다 짧으면 압축된 문자열 반환, 그렇지 않으면 원래 문자열 반환
return compressed.length() < str.length() ? compressed : str;
}
int main() {
std::string input = "aaabbbcccccddd";
std::string compressed = compressString(input);
std::cout << "Compressed string: " << compressed << std::endl;
return 0;
}
7. 부분 문자열 찾기
#include <iostream>
#include <string>
// 입력 문자열에서 특정 부분 문자열을 찾아 인덱스를 출력하는 함수
void findSubstrings(const std::string& str, const std::string& target) {
size_t found = str.find(target); // 특정 문자열의 첫 등장 위치 찾기
while (found != std::string::npos) {
// 특정 문자열을 찾을 때마다 해당 위치 출력
std::cout << "Found at index: " << found << std::endl;
// 찾은 위치 다음부터 다시 찾기 (중복된 부분 문자열 처리)
found = str.find(target, found + 1);
}
}
int main() {
std::string str = "hello, world! hello, universe!";
std::string target = "hello";
findSubstrings(str, target);
return 0;
}
8. 공백을 포함한 문자열 입력 받기
getline(cin, str);
'프로그래밍 언어 > C++\C' 카테고리의 다른 글
[C++] 네임스페이스와 ::연산자 - 코드 구조화와 충돌 방지의 핵심 (0) | 2023.08.22 |
---|---|
[C++] 문자열을 다룰 때 조심해야하는 이유 - 문자열 복사 (0) | 2023.08.21 |
[C++] STL에서의 unordered_map사용법과 map과의 차이점, unordered_set 사용법 (1) | 2023.08.21 |
[C++] Stack, Queue, 우선순위 큐에 구조체 넣는 법 (0) | 2023.08.16 |
[C++] Map, Set 사용하고 구조체까지 넣어보기 (0) | 2023.08.09 |