CPP_어소_73_tree (5)

CJB_ny·2022년 7월 19일
0

CPP_AROTHO

목록 보기
72/83
post-thumbnail

BST


  1. map을 사용할 때 포인터 타입을 사용하지 않는 이유.

  2. 첫번째 타입의 비교를 어떻게 할 것인가?

  3. operator 구현

  4. const wchar_t* => 문자열의 주소끼리 비교? ㄴㄴ


데이터 출력

int main()
{
	_wsetlocale(LC_ALL, L"korean");

	set<int> setInt;

	setInt.insert(100);

	const wchar_t* ptr = L"문자열";

	map<const wchar_t*, StdInfo> mapData;
	map<const wchar_t*, StdInfo>::iterator mapIter;

	StdInfo stu1(L"김남영", 26, MAN);
	StdInfo std2(L"김민성", 22, MAN);

	mapData.insert(make_pair(L"김남영", stu1));
	mapData.insert(make_pair(L"김민성", std2));

	mapIter = mapData.find(L"김민성");

	if (mapIter == mapData.end())
	{
		wcout << L"데이터를 찾을 수 없다." << endl;
	}
	else
	{
		wcout << L"이름 : " << mapIter->second.m_name << endl;
		wcout << L"나이 : " << mapIter->second.m_age << endl;
		wcout << L"성별 : ";
		if (MAN == mapIter->second.m_gender)
		{
			wcout << L"남자" << endl;
		}
		else if (WOMAN == mapIter->second.m_gender)
		{
			wcout << L"여자" << endl;
		}
		else
		{
			cout << L"알 수 없음" << endl;
		}

	}


	return 0;
}

일단 이렇게 가능하다.

주의? 할점 ❗

지금 wchar_t가 한 문자당 2바이트인데

이것을 cout 으로 출력을 할려고하면 안됨.

wcout으로 출력해야하고

콘솔창에 아무것도 안뜨거나 이상하게 뜰 수 있는 이유는

정확하게는 모르지만 UTF 문제임

그래서

_wsetloacle(LC_ALL, L"korean");

넣어 줘야함.

const wchar_t* 문제점 ❗

우리가

map<const wchar_t*, StdInfo> mapData;

이렇게 선언 했는데

타입으로 const wchar_t* 를 넣어 주게되면

정말 문자열로 비교를 해서 "이진 탐색 트리"를 구성했다고 볼 수 없다.

왜 ❓

문자열의 정체는 "주소값"이다.

주소값끼리 "비교연산" 하면 그냥 주소값의 크기를 비교해버리게 되니까..

문자가 누가 더 작고 그런것을 비교한게 아니라.

이렇게 찾을 수 있었던 이유는 find할때 문자열의 주소가 같았기 때문이다.

문자가 동일해서 찾은게 아니라! 주소값이 동일해서 찾은것이다.

문자열로 비교를 하고싶다면

map<const wchar_t*, StdInfo> mapData;

의 첫번째 타입을

문자열 객체를 다루는 것을 넣어주어야한다.

즉, 문자열을 다루는 클래스를 넣어 주어야한다.

이렇게 문자열 클래스 타입을 넣어 주어야한다.

string 헤더를 참조를 하면 문자열 클래스 사용이 가능하다.

wstring

지금 이녀석은 문자열 자체를 저장하고 있는데

원래는

wchar_t myArr[10] = L"abcdefg";

이렇게 선언 초기화를 해주면 L"abcdefg"라는 데이터를 배열에다가

"복사"를 해주는 것이다.


https://velog.io/@starkshn/CPP%EC%96%B4%EC%86%8C35%EB%AC%B8%EC%9E%90%EC%97%B4-1


마찬가지로

wstring str;
str = L"asdasd";

이 문자열 객체에 문자열을 집어 넣게되면은

(operator = 대입연산자 구현되어있음.)

본인이 자체적으로 가지고있는 "공간"안에

L"asdasd" 이 문자열을 가지고온다.

그러니까 wstring str의 str이라는 객체는

문자열 데이터(L"asdasd")를 따로 "관리"를 하고있는 것이다.

L"asdasd"의 주소를 관리 하는게 아니라.

읽기 전용 메모리 주소를 가르키는게 아니다❗

자체적으로 문자열을 관리를 한다.

또한 문자열 붙이기 가능.

이러한 operator들도 overloading이 되어있는 것이다.

그러면 문자열 무한정 늘리기 가능 ❓

ㄴㄴ 안됨.

그냥 느낌이 와야됨 이제는

"동적 할당"으로 늘리겠지 ㅄ아.

이렇게 무한정 넣기 ㄱㄴ? ㄴㄴ ㅂㄱㄴ.

배열을 처음부터 크게 할당 하는거 아님 ㅋㅋ!

이어붙일 때 힙메모리 구조를 받는다.

그렇다면

wstring은 우리가 배운 자료구조 중에 뭐랑 제일 비슷하노??

list랑 제일 비슷? (ㄴㄴ 병신아 )

굳이 따지자면 "가변 배열"이랑 가장 유사.

수정 가능한 이유?

str은 "자체적인 힙메모리 영역"을 들고있기 때문에

수정이 "가능"함.

operator

operator ==

str1 == str2

비교하면은

각자가 관리를 하고있는 주소를 비교를 하는 것이겠나?

ㄴㄴ.

문자열 하나하나를 다 비교를 해서 싹다 같으면 같다라고 인식을 할 것이다.

operator >, <

< , > 누가 크냐 작냐 따지는 것도 가능.

따라서 ❗

wstring을 map의 첫번째 타입으로 지정하게되면은

map은 템플릿이다 보니까

첫번째 타입으로 지정해준 객체들 간에 비교 연산자들을 통해서

루트의 왼쪽으로 갈지 오른쪽으로 갈지 정할 것이다.

그런데 첫번째 타입이

다양한 operator를 제공하는(구현이 되어있음)

wstring타입이라

map이 내가 넣어준 wstring (Key) 끼리 비교를 할 수 있다.

그러니까 const wchar_t* 에서 나타난 문제가 없어 질 것이다.

"문자 자체"를 비교를 할 것이기 때문에.

내가 만든 클래스

구냥 MyClass라고 아무렇게 클래스만들고

이렇게 make_pair 해서 넣어주게 되면은

'<' 라는 비교 연산자가 구현되어있지 않단다.

결과적으로 안되는 이유는

mapStdInfo는 template이다.

그런데 우리가 만든 operator가 구현되어있지 않은 클래스를

이진 탐색 트리로 구현을 할 때,

insert를 할 경우 루트에서부터 큰지 작은지를 비교를

첫번째 타입인 Key로 비교를 할껀데

'>', '>' 와 같은 operator를 구현해 놓지 않은 클래스들끼리 어떻게 비교를 해서

이진트리에 밀어 넣을 꺼임?

그리고 탐색은 어떻게 할꺼임??

const wchar_t* 경우

기본 포인터 자료형이기 때문에

첫번째 인자 Key값으로 넣어도 비교가 가능함.

그냥 주소 번지수가 크면 큰것이고 작으면 작은 그런거.

따라서 문자열 클래스 wstring으로 넣어 주어야한다.

다른 클래스도 되는데

그 클래스안에 operator들이 구현이 되어 있어야한다.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글