[C/C++] C++ STL Container [2]


์ปจํ…Œ์ด๋„ˆ(Container)?

C++ STL ์ปจํ…Œ์ด๋„ˆ๋Š” ๊ฐ™์€ ํƒ€์ž…์˜ ๊ฐ์ฒด๋“ค์„ ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. template์„ ์‚ฌ์šฉํ•˜์—ฌ ์ œ๋„ค๋ฆญํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํŠน์ •ํ•œ ์ž๋ฃŒํ˜•์— ์˜์กดํ•˜์ง€ ์•Š๋Š”๋‹ค.

์—ฐ๊ด€ ์ปจํ…Œ์ด๋„ˆ

vector, list์™€ ๊ฐ™์€ ์‹œํ€€์Šค ์ปจํ…Œ์ด๋„ˆ๋Š” ์›ํ•˜๋Š” ์กฐ๊ฑด์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค. ์—ฐ๊ด€ ์ปจํ…Œ์ด๋„ˆ๋Š” Key โ€“ Value ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๋Š” ์ปจํ…Œ์ด๋„ˆ๋กœ, ์š”์†Œ๋“ค์— ๋Œ€ํ•œ ๋น ๋ฅธ ์ ‘๊ทผ์„ ์ œ๊ณตํ•œ๋‹ค.

1. ๋งต (map)

ํ—ค๋”ํŒŒ์ผ <map>, namespace std
template <typename Key, typename Value> class map;


ํŠน์ง•

  • ๋…ธ๋“œ ๊ธฐ๋ฐ˜์ด๋‹ค.
class Node
{
public:
	Node* _left;
	Node* _right;
	pair<int, string> _data;
};
  • data์˜ ์ž๋ฃŒํ˜•์ด pair๋ผ pair๋กœ ์‚ฝ์ž…ํ•ด์•ผ ํ•œ๋‹ค.
int main()
{
	map<int, int> m1;
	
	m1.insert(pair<int, int>(2, 5));
	m1.erase(2);

	return 0;
}
  • Red-Black Tree(์ž๊ฐ€ ๊ท ํ˜• ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ)๋กœ ๊ตฌํ˜„๋˜์–ด ์žˆ๋‹ค. ๋•Œ๋ฌธ์— ์‚ฝ์ž…, ์‚ญ์ œ, ๊ฒ€์ƒ‰ ๋ชจ๋‘ O(logN). ์ตœ์•…์˜ ๊ฒฝ์šฐ์—๋„ O(logN)๋Š” ์ง€ํ‚ด.
  • key ๊ฐ’ ์ค‘๋ณต ์•ˆ ๋˜๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ ฌํ•˜์—ฌ ์ €์žฅ.
  • ์ •๋ ฌ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์ถ”๊ฐ€์ ์ธ ์ž‘์—…์ด ํ•„์š”ํ•ด์„œ ์›์†Œ์˜ ์‚ฝ์ž…/์‚ญ์ œ๊ฐ€ ๋นˆ๋ฒˆํ•  ๊ฒฝ์šฐ ์„ฑ๋Šฅ์ด ์ €ํ•˜๋œ๋‹ค.


์ฝ”๋“œ

#include<iostream>
#include<map>
using namespace std;

int main()
{
	map<int, int> m1;
	
	for (int i = 0; i < 100; i++)
	{
		m1.insert(pair<int, int>(i, i*2));
	}

	m1.erase(2); // key๊ฐ€ 2์ธ ๋…ธ๋“œ ์ œ๊ฑฐ
	
	map<int,int>::iterator findIt = m1.find(2); // key๊ฐ€ 2์ธ ๋…ธ๋“œ ์ฐพ๊ธฐ : ๋ชป ์ฐพ์Œ
	if (findIt != m1.end())
	{
		cout << "์ฐพ์Œ" << endl;
	}
	else { cout << "๋ชป ์ฐพ์Œ" << endl; }

	findIt = m1.find(4); // key๊ฐ€ 4์ธ ๋…ธ๋“œ ์ฐพ๊ธฐ : ์ฐพ์Œ
	if (findIt != m1.end())
	{
		cout << "์ฐพ์Œ" << endl;
	}
	else { cout << "๋ชป ์ฐพ์Œ" << endl; }

	for (map<int, int>::iterator it = m1.begin(); it != m1.end(); ++it)
	{
		pair<const int, int>& p = (*it);
		int key = it->first;
		int value = it->second;

		cout << key << " " << value << endl;
	}

	m1.insert(make_pair(1, 4)); // ์ด๋ฏธ ์žˆ๋˜ key๋ผ๋ฉด value ์ˆ˜์ • ์•ˆ ๋จ. return ํ•ด์ฃผ๋Š” pair.second๊ฐ€ false.

	// ์—†์œผ๋ฉด ์ถ”๊ฐ€, ์žˆ์œผ๋ฉด ์ˆ˜์ •ํ•ด ์ฃผ๋Š” ์ฝ”๋“œ
	map<int, int>::iterator findIt2 = m1.find(1);
	if (findIt2 != m1.end())
	{
		findIt2->second = 4;
	}
	else
	{
		m1.insert(make_pair(1, 4));
	}

	// ์‚ฌ์‹ค ์ด๊ฑด ์ด๋Ÿฐ ์‹์œผ๋กœ ์ œ๊ณต๋œ๋‹ค.
	m1[1] = 4;
	
	// ์ด๋ ‡๊ฒŒ ํ•ด๋„ key = 1000์ธ ๊ฐ’์ด ์ถ”๊ฐ€๋˜๋ฏ€๋กœ ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค..
	cout << m1[1000] << endl;

	return 0;
}


2. ํ•ด์‹œ๋งต (unordered map)

ํ—ค๋”ํŒŒ์ผ <unordered_map>, namespace std
template <typename Key, typename Value> class unordered_map;


ํŠน์ง•

  • Hash Table ๊ธฐ๋ฐ˜ (map์€ Red-black Tree)
  • ๊ฐ’ ์ค‘๋ณต ์•ˆ ๋˜๊ณ , ์ •๋ ฌ๋˜์ง€ ์•Š๊ณ  ๋žœ๋คํ•˜๊ฒŒ ์ €์žฅ๋œ๋‹ค.
  • insert, erase, find ๋ชจ๋‘๊ฐ€ O(1).
  • (์ค‘์š”) ๊ฒ€์ƒ‰ ์‹œ ํ•ด์‹œ ์ถฉ๋Œ์ด ์ผ์–ด๋‚˜์„œ O(N)๊นŒ์ง€๋„ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ์•ˆ์ •์ ์ธ ์†๋„๊ฐ€ ์ค‘์š”ํ•œ ์ž‘์—…์ด๋ผ๋ฉด ํ•ญ์ƒ O(logN)์ธ map์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์„ ์ˆ˜๋„ ์žˆ๋‹ค. ์ตœ์ ํ™”๊ฐ€ ์ค‘์š”ํ•˜๋‹ค๋ฉด ํ•ด์‹œ ํ•จ์ˆ˜๋ฅผ ์ž˜ ์งœ์„œ unordered map ์‚ฌ์šฉ.
  • ์ง์ ‘ ๋งŒ๋“  ํด๋ž˜์Šค๋ฅผ ๋„ฃ์œผ๋ ค๋ฉด ํ•ด์‹œ ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค. C++ STL์—์„œ int, string ๋“ฑ ๊ธฐ๋ณธ์ ์ธ ํƒ€์ž…๋“ค์— ๋Œ€ํ•œ ํ•ด์‹œ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฅผ ์ž˜ ํ™œ์šฉํ•ด์„œ ๋งŒ๋“ค๋ฉด ๋œ๋‹ค.
  • Bucket์„ ๋Š˜๋ ค์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ํ•ด์‹œ ํ•จ์ˆ˜๋ฅผ ๋ฐ”๊ฟ”์•ผ ํ•ด์„œ ๊ธฐ์กด ์›์†Œ๋“ค์„ ๋ชจ๋‘ ๋‹ค์‹œ insert ํ•ด์ค˜์•ผ ํ•˜๋Š”, O(N)์ด ๊ฑธ๋ฆฌ๋Š” rehash ์ž‘์—…์ด ์‹คํ–‰๋œ๋‹ค. (์•ฝ๊ฐ„ ๋ฒกํ„ฐ capacity ๋Š˜๋ฆฌ๋Š” ๋Š๋‚Œ)

Categories:

Updated:

Leave a comment