[STL] C++ map, multimap, unordered_map





결과

map 내림차순 결과






코드

#include <iostream>
#include <string>

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

int main() {
	
	// map<int, string> m;	// 오름차순
	map<int, string, greater<int>> m;	// 내림차순
	// multimap<int, string> m;	// 중복 key 가능

	// unordered_map<int, string> m;	// 정렬 x


	m.insert(make_pair(4, "d") );
	m.insert(make_pair(1, "a"));
	m.insert(make_pair(3, "c"));
	m.insert(make_pair(2, "b"));
	m.insert(make_pair(3, "c"));
	
	cout << "개수 : " << m.size() << "\n";
	
	// 3 키를 갖는 원소가 존재하면 해당 값 수정
	if(m.find(3) != m.end() ) m.at(3) = "w";

	m.erase(2);	// key 값

	for (auto i = m.begin(); i != m.end(); i++) {
		cout << i->first << " " << i->second << "\n";
	}
	cout << "\n";


	return 0;
}






1. map


map<int, string> m;	// 오름차순

- <키, 값> 의 구조를 갖는다.

ㄴ 여기서 키는 집합처럼 중복된 key는 갖을 수 없다.



- 해당 키가 이미 존재할 때, 값을 변경하도록 처리하기 위해서는 따로 검사하여 처리해주어야 한다. ( 글 하단에서 설명 )



- 자동으로 오름차순으로 정렬한다.


ㄴ 내림차순으로 정렬하기 위해서는 아래처럼 선언을 해준다.

map<int, string, greater<int>> m;	// 내림차순






2. multimap


multimap<int, string> m;	// 중복 key 가능

- map 라이브러리의 포함되어 있다.


- 기존의 map과는 다르게 동일한 Key를 갖을 수 있다.


- erase() 함수를 사용하여 삭제 시 값을 인수로 준다면 전부 지우지만

하나 씩 지우기 위해서는 find() 함수를 추가적으로 사용하여 삭제하여야 한다.


- at() 함수를 사용하여서 값을 변경할 수 없다.






3. unordered_map


unordered_map<int, string> m;	// 정렬 x

- 기존의 map과 동일하지만 정렬을 하지 않는다.



- 사용하기 위해서는 #include <unordered_map> 해주어야 한다.











insert(make_pair(E key, E value)) : 삽입

- pair을 생성한 후 <키,값> 을 삽입한다.


- 만약 키가 이미 존재할 경우 second의 false를 리턴한다.




erase(E key) 또는 erase(map<E>::iterator) : 삭제

- 키를 넣으면 삭제할 수 있다.


- 혹은 iterator을 인수로 주어서 삭제할 수도 있다.

ㄴ multimap일 경우 중복 값이 가능하므로 

키를 넣어 삭제 시 해당 값이 모두 삭제되지만

find를 사용하여 iterator을 인수로 주면 하나씩 삭제가 가능하다.





find(E e) : 탐색

- 존재하지 않는 값이면 map.end()를 리턴한다.

( end의 iterator )





at(E Key) = "수정할 값" : 수정


- 만약 삽입 시 이미 키가 존재할 경우 값을 변경해 주고 싶다면 해당 예처럼 하면 된다.

if( m.insert(make_pair(3, "w")).second == false ) m.at(3) = "w";

ㄴ 삽입 시 이미 키가 존재하므로 second의 false를 갖는다.

그러면 at() 함수를 사용하여 해당 값을 변경해주면 된다.






[STL] C++ priority_queue 우선순위 큐





결과

결과 - int 오름차순


결과 - string 내림차순





코드

#include <iostream>
#include <string>
#include <queue>
using namespace std;

int main() {
	// priority_queue<int> q;	// 내림차순 
	// priority_queue<int, vector<int>, less<int> > q;	// 내림차순
	priority_queue<int, vector<int>, greater<int> > q;	// 오름차순

	if (q.empty()) cout << "우선순위 큐가 비었습니다.\n";

	q.push(4);
	q.push(4);
	q.push(2);
	q.push(1);
	q.push(3);

	cout << "맨 위 : " << q.top() << "\n";


	cout << "나가는 순서 : ";
	while (!q.empty()) {
		cout << q.top() << " ";
		q.pop();
	}
	cout << "\n";

	return 0;
}




우선순위 큐(priority_queue) : 스택(stack)과 큐(queue) 같은 자료형.

우선순위 큐는 각 원소들이 우선순위를 갖는다.




내림차순, 오름차순

- priority_queue는 기본적으로 내림차순으로 정렬한다.


- 오름차순으로 정렬하기 위해서는

priority_queue<int, vector<int>, greater<int> > q;	// 오름차순

해야한다.




empty() : 큐가 비었는지 검사




push() : 데이터를 삽입




size() : 길이를 리턴




top() : 가장 우선순위가 높은 원소

- pop() 했을 시 가장 먼저 나간다.




pop() : 데이터를 삭제







[STL] C++ queue 생성 및 삽입, 삭제





결과

결과





코드

#include <string>
#include <iostream>
#include <queue>
using namespace std;

int main() {
	queue<int> q;

	if (q.empty()) cout << "큐가 비었습니다.\n";

	q.push(4);
	q.push(2);
	q.push(1);
	q.push(3);

	cout << "맨 앞 : " << q.front() << "\n";
	cout << "맨 뒤 : " << q.back() << "\n";


	cout << "나가는 순서 : ";
	while (!q.empty()) {
		cout << q.front() << " ";
		q.pop();
	}
	cout << "\n";

	return 0;
}



Queue : 후입후출(or 선입선출)의 구조로 가장 먼저 들어온 것이 가장 먼저 나간다.




empty() : 큐가 비어있는지 검사

- 비어있지 않다면 false를 return 한다.




push() : 데이터를 삽입(push) 




front() : 가장 앞 값을 리턴

- 가장 앞(가장 먼저 나갈) 값을 리턴




back() : 가장 뒤 값을 리턴

- 가장 뒤(가장 나중에 나갈) 값을 리턴




size() : 큐의 길이를 리턴




pop() : front() 값을 삭제(pop)

- 큐는 선입선출의 구조이므로 가장 앞에(가장 먼저 들어온) 값을 삭제한다.


- return 형이 void형이므로 pop()을 해주기 전에 front() 값을 따로 저장해두어야만 이용할 수 있다.


- 큐가 비었을 경우 pop()을 한다면 에러가 발생한다.








pair을 사용하여서 queue 2개 값 저장하기



링크

[C++/STL] - C++ pair 사용하여 쌍으로 값저장




C++ pair 사용하여 쌍으로 값저장, vector를 사용한 예

 

 

 

 

Pair<[Type], [Type] > 이란?

 

- 2개의 각각 지정한 타입의 값을 저장한다.

 

- 저장한 값은 .first 와 .second로 각각 접근할 수 있다.

 

- 2개의 연관된 값을 같이 저장할 수 있어서 관리를 용이하게 할 수 있다.

 

- 특히, 연관된 2개의 값에서 각각의 조건에 따라 정렬한 결과를 얻고자 할 때 사용하면 좋다. 

( 즉, 2개의 정렬 조건으로 정렬을 하고 싶을 때)

 

 

 

 

 

 

[ 코 드 ]

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

bool comp(pair<int, double> a, pair<int, double> b) {
    if (a.second == b.second) a.first < b.first;
    return a.second > b.second;
}

int main() {
    vector<int> v;
    int N = 8;
    pair< int, int> test = make_pair(1, 2);
    vector<pair<int, double>> vv;
    v.push_back(1);
    v.push_back(3);
    v.push_back(2);
    v.push_back(1);
    v.push_back(0);
    
    for (int i = 0; i < v.size(); i++) {
        vv.push_back(make_pair(i + 1, (double)v[i] / N));
        N -= v[i];
    } // (1, 0.125) (2, 0.4285) (3, 0.5) (4, 0.5) (5, 0) 순으로 데이터가 있다.
	

    sort(vv.begin(), vv.end(), comp); // 2번째 값이 큰 순으로, 1번째 값이 작은 순으로 정렬을 한다.
    
    for (int i = 0; i < vv.size(); i++) {
        cout << vv[i].first << " " << vv[i].second << "\n";
    }

	return 0;
}

 

- 14라인 : pair변수를 선언하고 값을 할당한다. 값을 줄 때는 make_pair( 값1, 값2)를 사용해준다.

 

- 15라인 : vector의 pair타입을 사용하여 선언함으로써 pair 변수를 저장할 수 있게 한다.

 

- 23라인 : pair 타입을 저장하는 vector이므로 make_pair을 사용해 주어서 값을 저장하고 있다.

 

 

 

 

 

 

[ 결 과 ]

 

 

 

- 결과를 보면 2번째 값에 따라서 내림차순 정렬이 되며, 2번째 값이 같을 경우 1번째 값에 따라 오름차순 정렬이 되었다.

 

 

 

 

 

C++ vector 오름차순, 내림차순으로 정렬하기

 

 

 

 

 

sort() 함수

 

- 사용하기 위해서는  #include <algorithm>  을 해주어야 한다.

 

- 디폴트(기본)적으로 오름차순으로 정렬을 해준다.

 

- 내림차순으로 정렬을 하고자 하거나 특정 조건에 따라서 정렬을 하고자 할 때는 비교함수를 만들어서 인수로 주어야 한다.

( 비교함수명은 본인이 지정하면 된다. )

 

- 비교함수는 리턴형은 bool 형으로 매개변수들의 타입은 정렬하는 vector의 저장하는 값의 타입을 준다.

 

- sort() 함수는 퀵 솔트(Quick sort)으로 구현되어 있어 빠른 속도로 정렬을 한다. 

 

- sort() 함수를 사용한다면 일반적인 배열또한 정렬할 수 있다.

 

 

 

 

[ 코 드 ]

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

bool comp(int a, int b) {
    return a > b;
}

int main() {
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(7);
    v.push_back(8);
    v.push_back(1);
    v.push_back(5);
    
    for (int i = 0; i < v.size(); i++) cout << v[i] << " ";
    cout << " 정렬 전\n\n";

    sort(v.begin(), v.end());   // 오름차순 정렬

    for (int i = 0; i < v.size(); i++) cout << v[i] << " ";
    cout << " 오름차순 정렬 후\n\n";

reverse(v.begin(), v.end());	// 1. 내림차순 정렬 (오름차순정렬 후 같이 사용)
    sort(v.rbegin(), v.rend());		// 2. 내림차순 정렬 ( rbegin()과 rend()를 사용)
    sort(v.begin(), v.end(), comp); // 3. 내림차순 정렬 (비교함수를 사용)

    for (int i = 0; i < v.size(); i++) cout << v[i] << " ";
    cout << " 내림차순 정렬 후\n\n";

	return 0;
}

 

 

- 23라인 : 추가적으로 비교함수를 인수를 주지 않았다. 그러므로 디폴트 값인 오름차순으로 정렬이 된다.

 

 

※ 

- 28라인 : reverse 함수는 뜻 그대로 반대로 뒤집는다. 그래서 이를 오름차순으로 정렬한 후 사용한다면 내림차순으로 정렬한 것과 같은 결과를 얻을 수 있다.

( reverse 함수또한 사용하기 위해서는 #incldue <algorithm> 을 해주어야 한다.

 

- 29라인 : 오름차순 정렬할 때는 인수로 v.begin(), v.end()를 주었었다. 하지만 이대신 v.rbegin(), v.rend()를 주면 내림차순으로 정렬이 된다. ( r은 아마 reverse )

 

- 30라인 : 추가적으로 비교함수를 인수로 주었다. 비교 함수에서 준 조건에 따라 내림차순으로 정렬이 된다. 이 방법은 굳이 내림차순 정렬만이 아니라 특정 조건에 따라서 정렬을 하고자 할 때 사용할 수 있다.

 

 

 

 

 

[ 결 과 ]

 

 

결과를 보면 각각 오름차순과 내림차순으로 각각 잘 정렬된 것을 확인할 수 있다.

 

 

 

 

 

 

 

 

 

C++ string to int, int to string 형변환 하기 , string 문자열에서 숫자만 선택해 형변환

 

 

 

int stoi (const string& str [, size_t* idx = 0, int base = 10]) : string to int

 

- string을 int로 바꾸어주기 위해서 stoi() 함수를 사용해 준다.

(stoi -> string to integer를 줄인 것이다. 그래서 이를 응용해 생각해보면, stoll은 string to long long으로 long long 형으로 형변환 할 수 있다.)

 

 

- stoi()을 사용하기 위해서는 #include <string> 을 해주어야 한다.

(※ #include <string.h>가 아닌 <string>을 해주어야 한다. )

 

 

- 3번 째 인수를 보면 디폴트 값으로 10이 주어져 있다. 이를 변경해주면 n진수의 문자열을 10진수의 수로 변경할 수 있다.

 

 

 

 

 

 

 

string to_string(int val) : int to string

 

- 함수명 그대로 string 형으로 바꾸어 줄수 있다.

 

- 인수로는 int 뿐만 아니라 double형 long long형 등등... 을 사용할 수 있다.

 

- to_string()을 사용하기 위해서는 #include <string> 을 해주어야 한다.

 

 

 

 

 

 

 

[ 코 드 ]

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

int main() {
	string a = "1234", b = "1a2b3c";
	int num = 4321;

	// 1. string -> int
	cout << stoi(a) << "\n";
	// 8진수 1234를 -> 10진수로 변환
	cout << stoi(a,nullptr,8) << "\n";


	// 2. string 문자열에서 숫자만 구분하여 출력
	for (int i = 0; i < b.size(); i++) {
		if (b[i] >= '0' && b[i] <= '9') cout << b[i] - '0';
	}
	cout << "\n";


	// 3. int -> string
	string s = to_string(num);
	string r = "결과 = ";

	r += num;
	cout << r << "\n";

	r = "결과 = ";
	r += s;
	cout << r << "\n";

	return 0;
}

 

 

- 10라인 : 문자열의 숫자만 있을 경우 그냥 stoi를 사용해주면 숫자로 변경 할 수 있다.

 

만약 문자열의 숫자와 문자가 섞여 있다면, 앞에서부터 문자가 나올 때까지의 숫자만을 변환해 준다.

 

 

 

- 12라인 : 진수를 지정해주었다. 8진수인 "1234"를 10진수로 변환해준다. 결과는 668.

 

 

 

- 17라인 : string 문자열을 하나씩 접근할 때는 char형이다. 그래서 숫자일 경우 '0'(=48) 와 '9'(=57) 사이의 값을 가지면 숫자이다.

 

만약 숫자일 경우 '0'(=48)을 빼주면 숫자를 구할 수 있다.

 

ex) 문자가 '2'일 경우 아스키 코드 상 50이므로 여기에 '0'(=48)을 빼주면 숫자 2를 얻을 수 있다.

 

 

 

- 23라인 : to_string() 을 사용하여서 숫자를 문자열로 바꾸었다.

 

 

 

 

[ 결 과 ]

 

 

숫자를 문자열로 변경하지 않은 채 문자열과 더해 주었을 때는 아무것도 출력되지 않았다.

 

하지만 to_string으로 문자열로 변환한 후 더해준 문자열을 출력해주었을 때는 잘 출력되는 것으로 보아 무자열로 잘 변환 되었다는 것을 확인할 수 있다.

 

 

 

 

 

참조

http://www.cplusplus.com/reference/string/stoi/

 

stoi - C++ Reference

function template std::stoi int stoi (const string& str, size_t* idx = 0, int base = 10); int stoi (const wstring& str, size_t* idx = 0, int base = 10); Convert string to integer Parses str interpreting its content as an integral number of the spe

www.cplusplus.com

 

 

C++ 제곱근 구하기, n승 값 구하는 방법 : sqrt(), pow()

 

 

 

 

 

 

double sqrt (double x);

 

 

- 사용하기 위해서는 #include <math.h> 혹은 #include <cmath> 를 해주어야 한다.

 

- 리턴형은 double 형으로 인수로 준 값의 양의 제곱근을 리턴한다.

 

 

 

 

 

 

 

double pow (double a, double n);

 

 

- 사용하기 위해서는 #include <math.h> 혹은 #include <cmath> 를 해주어야 한다.

 

- 리턴형은 double으로서 a의 n제곱을 한 값을 리턴한다.

 

 

 

 

 

[ 코 드 ]

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

int main() {
	int a = 3, n = 4, b = 144;

	cout << a << "의 " << n << "승 = " << pow(a, n) << "\n";

	cout << b << "의 " << "양의 제곱근 = " << sqrt(b) << "\n";

	return 0;
}

 

 

 

 

 

[ 결 과 ]

 

 

 

 

참조

http://www.cplusplus.com/reference/cmath/pow/

 

pow - C++ Reference

1234567891011 /* pow example */ #include /* printf */ #include /* pow */ int main () { printf ("7 ^ 3 = %f\n", pow (7.0, 3.0) ); printf ("4.73 ^ 12 = %f\n", pow (4.73, 12.0) ); printf ("32.01 ^ 1.54 = %f\n", pow (32.01, 1.54) ); return 0; }

www.cplusplus.com

 

 

C++ 소수 찾기, 검사하기 [에라토스테네스의 체] 하는 방법

 

 

 

 

소수 찾는 알고리즘 [에라토스테네스의 체]

 

 

- 2부터 지정한 수까지의 소수들을 찾을 수 있다.

 

-  i(=2)부터 ~ 지정한 수의 제곱근까지 수들의 배수들을 제외하는 과정을 반복하면서 소수를 판별한다. 

( 어느 수의 배수라는 것은 소수가 아니라는 의미)

 

 

 

 

 

->  참조

https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4

 

 

 

 

[ 코 드 ]

#include <iostream>
#include <math.h>
#define N 500
#define N2 199
using namespace std;

bool sosu(int n) {
	int k = (int)sqrt(n);
	for (int i = 2; i <= k; i++) {
		if (n % i == 0) return false;
	}
	return true;
}

int main() {
	bool* b = new bool[N + 1];	// 숫자 A을 배열의 A번에 저장하기 위하여 크기 N+1
	for (int i = 2; i < N+1; i++) b[i] = true;
	
	for (int i = 2; i * i < N+1; i++) {
		for (int k = i * i; k < N+1; k += i) {
			b[k] = false;
		}
	}

	// 결과
	cout << N << "까지의 소수들\n";
	for (int i = 2; i < N + 1; i++) if (b[i]) cout << i << ", ";

	cout << "\n\n" << N2 << "는 ";
	if (sosu(N2)) cout << "소수입니다.\n";
	else cout << "소수가 아닙니다.\n";

	return 0;
}

 

 

16~23 라인 : N+1만큼의 크기를 갖는 bool 배열을 선언하고 true로 초기화 해준다. 그리고 N까지 i의 배수들을 false로 바꾸는 과정을 반복한다.

 

 

 

7라인 : sosu함수는 인수로 받은 수가 소수인지 판별하여서 참이면 true를 거짓이면 false를 리턴한다.

 

8라인 : sqrt(n) 함수는 제곱근을 구하는 함수로서 #include <math.h> 를 해주어야 한다.

 

9라인 : for문을 보면 2부터 n의 제곱근인 k까지 검사한다. k까지만 검사해도 되는 이유는

 

ex) n = 16 일 때, k= 4

그러면  "4이전 i=2일 때 검사한 것 "  =  "4이후 i=8일 때 검사한 것"

즉, 2 x 8 = 8 x 2 이므로 제곱근인 k까지만 검사해주면 된다.

 

 

 

 

 

[ 결 과 ]

 

 

결과를 보면 2부터 500전까지의 소수들을 출력한다.

 

또한, 199가 소수인지 아닌지 판별한다.

 

 

 

 

 

 

 

 

 

+ Recent posts