[C++] C++ string 문자열 붙이기 시간복잡도

hwhyeons·2024년 7월 22일

C++은 C의 char* 또는 char[] 형태로 문자열을 사용할 수 있지만,
추가로 C++은 STL은 편리하게 string이라는 클래스를 제공합니다.


C언어를 학교에서 처음 배울 때, 자바나 파이썬을 C언어보다 먼저 접했던 저에게 char*로 문자열을 처리하는 것이 너무나도 어려웠던 기억이 있습니다.

이를 이용해서 문자열 두개를 합치거나, 문자열을 자르거나 등의 행위를 string에서 제공하는 함수로 쉽게 처리할 수 있습니다.



C++ STL string의 특징

STL의 string은 자바, 파이썬 등의 타언어와는 구별되는 특징이 있습니다.
바로 문자열이 가변이라는 것입니다.

Java, Python 등은 비록 똑같은 문자열 변수에 다른 문자열을 다시 할당할 수 있으나, 이는 실제 객체 내부의 문자열이 바뀌는 것이 아닌 다른 객체를 가리키게 됩니다.

Java에서 문자열을 반복적으로 붙일 때 String이 아닌 StringBuilder을 사용하라는 이유가 여기에서 나온 이유입니다.
Java에서 String은 불변이기 때문에, s += s1같은 동작을 반복하게 되면
문자열 복사가 계속 일어나게 되는것이죠.


C++ STL의 string의 가변적이라는 특징이, 문자열을 붙이는 작업에서 더 빠른 시간안에 처리할 수 있도록 하는 역할을 해줄 수 있습니다.

STL string은 멤버 함수로.append()를 제공합니다.
기존 문자열에 문자열을 추가로 붙여넣는 행동으로, C언어의 strcat과 유사합니다.


STL의 string은 내부가 가변 배열 형태로 구성되어있기 때문에, append()를 이용해서 기존에 문자들을 보관하고 있던 배열에 문자를 붙이는 형태로 빠르게 문자열 붙이기가 가능합니다.



string의 += operator

하지만 STL string은 += operator을 이용하게 되면 자동으로 append()를 호출합니다.
따라서 +=을 반복해도 문자열을 합치고 다시 복사하고 행위가 아닌
append()를 내부적으로 호출하는 방식이라, 추가로 뒤에 붙이고자 하는 문자열의 크기가 K면, 시간복잡도가 O(K)로 작습니다.'


하지만 여기서 주의해야할 점이 있습니다.

일반적으로

a += ba = a+b는 동일합니다.
문제는 STL의 string은 둘의 동작이 다르다는 것이죠.


아래 코드를 실행하면 약 4~5ms 정도 소요됩니다
std::string s;
clock_t start = clock();
for (int i = 0; i < 100000; i++) {
	s += "1234";
}
cout << "실행시간 : \n";
clock_t finish = clock();
cout << finish - start;

하지만, 아래 코드를 실행하면 1100ms 정도 소요됩니다

std::string s;
clock_t start = clock();
for (int i = 0; i < 100000; i++) {
	s = s + "1234";
}
cout << "실행시간 : \n";
clock_t finish = clock();
cout << finish - start;

달라진 부분은 s += "1234"s = s+"1234"밖에 없는데 말이죠!

위에서 언급했듯이, +=는 내부적으로 append() 함수를 호출하도록
연산자 오버로딩 되어있습니다.


STL string의 기본 형태인 basic_string.h를 참고하면

와 같이 += 연산은 append()를 호출하게 되어있습니다.

즉 예를 들어 s1 += s2 은 s1.append(s2)와 거의 동일하다고 볼 수 있습니다.

s1의 문자열을 저장하는 배열에 s2의 내용을 이어 붙이기만 하므로 시간소모가 매우 짧은 것이죠.


그에 반해 s = s + "1234"을 반복하면 문자열 복사(또는 이동)를 반복하게 됩니다.


따라서 문자열을 반복적으로 붙여야 할 때는, += 연산자 또는 .append()등을
호출해서 사용해야합니다.

0개의 댓글