[자료구조] String

치치·2025년 1월 3일
0

자료구조C++

목록 보기
9/17
post-thumbnail

String

문자열을 다루기 위한 매우 중요한 자료형이다
동적으로 메모리를 할당하여 크기를 조정하기 때문에 문자열의 길이에 상관이 없다

문자열 stl 구현해보기

클래스 & 생성자

  • String이란 이름의 클래스를 생성해주고 문자열의 사이즈를 반환할 변수 & 문자열을 동적으로 생성할 pointer 포인터를 선언해준다

  • 생성자에서 초기화 해주기

#include <iostream>

using namespace std;

class String
{
private:
	int size;
	// 문자열을 동적으로 생성할 포인터
	char* pointer;


public:
	String()
	{
		size = 0;
		pointer = nullptr;
	}

문자열 하나씩 받기

void operator = (const char* content)
{
	size = strlen(content) + 1;

	if (pointer == nullptr)
	{
		pointer = new char[size];

		for (int i = 0; i < size; i++)
		{
			pointer[i] = content[i];
		}
	}
	else
	{
		// 새로운 배열
		char* newpointer;
		newpointer = new char[size];

		for (int i = 0; i < size; i++)
		{
			newpointer[i] = content[i];
		}
		// 기존의 배열 해제
		delete[] pointer;
		pointer = newpointer;
	}
}

void operator = (const char * content)

  • operator = -> 대입연산자 오버로딩
    void operator = (const char * content) 는 메인함수에서 객체에 대입한 값이 인수로 들어와서 함수안에서 처리해주는 역할이다
    ex) 클래스의 객체를 생성한 뒤 객체에 값을 대입(매개변수로 들어올 값이 char 형식이기에 문자열이 하나씩 들어온다)
int maine()
{
	String string;
    string = "BABABA";
}

size

  • 매개변수로 들어온 값 + 1 하여 size값을 정해준다
    strlen : 문자열의 길이를 계산하는 함수, null문자를 제외한 길이를 반환한다
  • 문자열은 NULL문자를 포함하기 때문에 strlen에 NULL문자 + 1 까지 해줘야 size값이다

pointer로 새 배열 생성

  • 만약 pointer가 가리키는 곳이 nullptr이라면 -> 문자열이 하나도 없다는 것
    -> 동적으로 새 배열을 만들고 크기를 할당해주어야함

  • 새로 동적할당한 배열을 pointer로 접근해서 인수로 들어온 content의 문자열을 하나씩 넣어준다

if (pointer == nullptr)
{
	pointer = new char[size];

	for (int i = 0; i < size; i++)
	{
		pointer[i] = content[i];
	}
}

pointer가 이미 배열을 할당하고 있다면?

  • 새로운 포인터를 하나 만들어서 동적배열을 할당해준다

  • 새로운 동적배열에 인수로 들어온 content의 문자열을 할당해주고 기존의 배열을 해제한다

  • newpointer 포인터는 함수안에서 생성했기 때문에 함수가 종료되면 사라진다. 따라서 pointer 포인터만 새로 할당된 배열을 가리킨다

  • 메인함수에서 작동했을 때, 문자열이 바뀌는 것을 알 수 있다
    ex) 기존에 Banana 문자열은 사라지고 Milk로 변경된다

int main()
{
	String string;
    string = "Banana";
    string = "Milk";
}

Append( )함수 -> 문자열 추가하기

void Append(const char* word)
{
	// 기존 크기 + 매개변수 문자 크기
	size = strlen(word) + strlen(pointer) + 1;

	char* newPointer = new char[size];

	// 기존 값 넣기
	for (int i = 0; i < strlen(pointer); i++)
	{
		newPointer[i] = pointer[i];
	}

	// 추가된 값 넣기
	for (int i = 0; i < strlen(word); i++)
	{
		newPointer[strlen(pointer) + i] = word[i];
	}
	delete[] pointer;
	pointer = newPointer;
}
  • size값을 기존에 할당하고 있던 null문자를 포함한 크기 + 새로 들어온 매개변수 크기로 할당
  • 새로운 newpointer를 만들어서 size 크기의 새 배열을 동적할당 해준다
  • 새 배열에 기존의 문자열 길이만큼 값을 복사하여준다
  • 기존 문자열 이후의 범위부터 새로 들어온 문자열을 대입해준다
// 추가된 값 넣기
for (int i = 0; i < strlen(word); i++)
{
	newPointer[strlen(pointer) + i] = word[i];
}
  • 기존의 배열을 해제하고 새로 할당해준 배열로 pointer를 연결시켜준다

Compare( ) 함수 -> 문자열 비교하기

  • 함수의 반환형은 int로
    문자열이 서로 같으면 0
    현재 문자열 > 새로 들어온 문자열 1
    현재 문자열 < 새로 들어온 문자열 -1 을 반환

  • 문자열의 길이가 서로 다를 경우, 값이 제대로 나오지 않아 추가적인 조건을 더 넣어주었다
    현재 문자열의 길이 > 새로 들어온 문자열의 길이 1
    현재 문자열의 길이 < 새로 들어온 문자열의 길이 -1 반환

// 둘이 같으면 0 현재pointer> 새로word 1 / -1
int Compare(const char* word)
{
	int count = 0;

	for (int i = 0; i < strlen(word); i++)
	{
		if (pointer[i] != word[i])
		{
			break;
		}
		else
		{
			count++;
		}
	}

	if (strlen(word) == count)
	{
		return 0;
	}

	int thisString = 0;
	int otherString = 0;

	for (int i = 0; i < strlen(pointer); i++)
	{
		thisString += pointer[i];
	}
	for (int i = 0; i < strlen(word); i++)
	{
		otherString += word[i];
	}

	if (thisString > otherString)
	{
		return 1;
	}
	else
	{
		return -1;
	}
}
  • 두 문자열을 비교하여 하나라도 다르면 바로 break로 반복문을 빠져나오고 같은 문자열이 있다면 count증가

  • count값이 strlen(word)와 같다는 건 문자열이 동일하다는 의미 return 0

  • 문자열이 서로 다를 경우 break로 반복문을 빠져나온 뒤 아래의 반복문 진입

  • 각각의 문자열들의 값을 int형으로 누적시킨다

  • 두 문자열의 아스키코드 값으로 비교하여 값을 return


인덱스 값 반환 & 소멸자

const char & operator [ ] (const int & index)

  • 연산자 오버로딩으로 메인함수에서 배열의 인덱스값을 매개변수로 가져온다 (&이기 때문에 참조로 가져옴(값 복사x))
  • 반환되는 배열 인덱스의 값은 const로 상수형태로 반환

~String( ) 소멸자

  • 포인터가 가리키는 곳에 할당된 메모리가 있다면 delete [ ] 로 모든 배열의 요소를 해제
// 인덱스 값 반환 
const char& operator [] (const int& index)
{
	return pointer[index];
}
~String()
{
	if (pointer != nullptr)
	{
		delete[] pointer;
	}
}

Size( ) 함수 -> size 반환

  • 상수형태로 값이 반환된다
    -> 문자열의 길이는 null문자도 포함되기 때문에 반환될때는 null문자를 제외한다
const int& Size()
{
	// null문자 제외
	return size - 1;
}

메인함수

  • String 클래스 타입의 객체를 생성해주고 대입연산자 오버로딩을 통해 객체에 값을 대입

  • string = "APPLE"; 을 대입한 뒤 값을 바꿔 string = "BANANA";로 대입 할 경우 기존의 APPLE 문자열은 해제되고 새로운 문자열이 할당된다

  • 문자열 비교함수인 Compare쪽에선 현재 문자열보다 비교할 문자열의 길이가 더 길기 때문에 결과값이 -1이 나와야한다

int main()
{
	String string;

	string = "APPLE";

	for (int i = 0; i < string.Size(); i++)
	{
		cout << string[i];
	}

	cout << endl;

	string = "BANANA";
	string.Append("MILK");

	for (int i = 0; i < string.Size(); i++)
	{
		cout << string[i];
	}

	cout << endl;


	string = "ABCD";

	cout << string.Compare("ABCCCCCC");
	return 0;
}

출력값:


⭐ string에 += & push_back()

✅ +=

string에 += 으로 '문자'나 "문자열"을 추가할 수 있다.

string s = "hi";
s += '!';
s += "Hello";
cout << s; // "hi!Hello"

✅ push_back()

string에 push_back()으로 문자 추가 시 char 만 가능하다. 문자열 불가능

string s = "abc";

s += 'd';         // OK → "abcd"
s += "efg";       // OK → "abcdefg"

s.push_back('h'); // OK → "abcdefgh"
s.push_back("ij"); // ❌ 컴파일 에러 (char*는 안 됨)
profile
뉴비 개발자

0개의 댓글