ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C, C ++ 표준 라이브러리와 STL 정리
    Problem Solving/PS를 위한 C++ 지식 2020. 3. 18. 22:19

    C++ 표준 라이브러리<algorithm>

    reverse

    • 원소들을 거꾸로 뒤집어 준다.

    [예제]

    #include <string>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int main() {
    	vector<int> arr = { 1,2,3,4,5 };
    
    	reverse(arr.begin(), arr.end());
    	
    	for (int n : arr)
    		cout << n << " ";
    
    	cout << endl;
    
    	string str = "Hello World!";
    
    	reverse(str.begin(), str.end());
    	
    	cout << str << endl;
    	cout << endl;
    
    	vector<string> strArr = { "apple", "banana", "tomato", "peach" };
    
    	reverse(strArr.begin(), strArr.end());
    
    	for (string tmp : strArr)
    		cout << tmp << " ";
    	cout << endl;
    
    	return 0;
    }

     

    copy 

    • 배열 복사할때 유용하다.
    • copy(원본의 시작 주소, 원본의 마지막 주소, 사본의 시작 주소); 
    • copy 함수는 [시작주소 , 마지막주소) 반열린 구간으로 동작된다. 따라서 원본의 마지막 주소 +1을 해줘야한다.

    [예제 1 : n 크기의 1차원 배열 a를 1차원 배열 b에 복사하기]

    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int a[5];
    int b[5];
    
    int main() {
    
    	int n = 5;
    	for (int i = 0; i < n; i++) {
    		a[i] = 7;
    	}
    
    	copy(&a[0], &a[n-1] + 1, &b[0]);
    
    	for (int i = 0; i < n; i++) {
    		cout << b[i];
    	}
    
    	return 0;
    }

     

    [예제 2 : n x m 크기의 2차원 배열 a를 2차원 배열 b에 복사하기]

    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int a[5][5];
    int b[5][5];
    
    int main() {
    
    	int n = 5, m = 5;
    	for (int i = 0; i < n; i++) {
    		for (int j = 0; j < m; j++) {
    			a[i][j] = 7;
    		}
    	}
    
    	copy(&a[0][0], &a[n-1][m-1] + 1, &b[0][0]);
    
    	for (int i = 0; i < n; i++) {
    		for (int j = 0; j < m; j++) {
    			cout << b[i][j];
    		}
    		cout << endl;
    	}
    
    	return 0;
    }

    next_permutation, prev_permutation

    • next_permutation : 특정 원소들의 다음 순열을 얻는다.
    • prev_permutation : 특정 원소들의 이전 순열을 얻는다.
    • 순열을 구할 때 유용하다, do while 문을 사용해서 쓴다.
    • 주의 : 대상 배열(벡터)에 중복된 원소가 존재하면, 중복된 원소를 제거하고 순열을 구해준다.
    • 사용전에 원소들이 오름차순으로 정렬된 상태여야 모든 순열을 구할 수 있다. 

    [예제 1 : next_permutation]

    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int main() {
    	int arr[5] = { 0,1,2,3,4 };
    
    	do {
    		for (int n : arr) {
    			printf("%d ", n);
    		}
    		puts("");
    	} while (next_permutation(arr, arr+5));  //다음 순열을 구한다. 다음 순열이 없으면 false return
    	
        // 문자열에 대해서도 아래와 같이 가능하다.
        // 순열을 돌리면 31142 와 같은 숫자가 2번 나올 수 있다.
    	// 하지만 next_permutation은 중복을 제거하기 때문에 1번만 나온다.
    	string s = "31421"; 
    
    	sort(s.begin(), s.end());
    
    	do {
    		cout << s << endl;
    	} while (next_permutation(s.begin(), s.end()));
    
    	return 0;
    }

    [예제 2 : prev_permutation]

    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int main() {
    	int arr[5] = { 4,3,2,1,0 };
    
    	do {
    		for (int n : arr) {
    			printf("%d ", n);
    		}
    		puts("");
    	} while (prev_permutation(arr, arr+5));  //이전 순열을 구한다. 이전 순열이 없으면 false return
    	
    	return 0;
    }

    fill

    • 특정 범위를 어떤 값으로 채운다.
    • fill(시작주소, 마지막주소, 채울 원소값);
    • fill 함수는 [시작주소 , 마지막주소) 반열린 구간으로 동작된다. 따라서 원본의 마지막 주소 +1을 해줘야한다.
    • <string.h>의 memset은 byte 단위로 동작하기 떄문에 정수나 문자에 대해 동작하지 않는다. 이때 fill을 쓰면 된다.

    [예제 1 : 1차원 배열 arr을 7로 채우기]

    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int main() {
    	int arr[10]; 
    
    	fill(&arr[0], &arr[9]+1, 7); //마지막 주소를 포함하지 않은 반열린 구간이기에 +1을 해준다.
    
    	for (int i = 0; i < 10; i++)
    		cout << arr[i] << endl;
    
    	return 0;
    }

    [예제 2 : 2차원 배열 arr을 7로 채우기]

    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int main() {
    	int arr[10][10];  
    
    	fill(&arr[0][0], &arr[9][9] +1 , 7);
    
    	for (int i = 0; i < 10; i++) {
    		for (int j = 0; j < 10; j++) {
    			cout << arr[i][j];
    		}
    		puts("");
    	}
    		
    	return 0;
    }

    ✔️ sort 함수

    특정 원소들을 정렬 시켜준다.

    fill 함수는 [시작주소 , 마지막주소) 반열린 구간으로 동작된다. 따라서 원본의 마지막 주소 +1을 해줘야한다.

    sort(시작주소, 마지막 주소, less<자료형>()); // defalut 오름차순이다.

    sort(시작주소, 마지막 주소, greater<자료형>()); //이렇게 해주면 내림차순으로 동작한다.

     

    💾 [예제 1 : 1차원 배열 arr 정렬]

    더보기
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int main() {
    	int arr[10] = { 4,7,2,9,5,0,8,1,6,3 };
    
    	sort(arr, arr + 10); //오름차순
    
    	for (int i = 0; i < 10; i++) {  
    		cout << arr[i] << " ";
    	}
    
    	cout << endl;
    
    	sort(arr, arr + 10, greater<int>());  //내림차순
    
    	for (int i = 0; i < 10; i++) { 
    		cout << arr[i] << " ";
    	}
    
    	return 0;
    }

    💾 [예제 2 : 1차원 vector arr 정렬]

    더보기
    #include<iostream>
    #include<algorithm>
    #include<vector>
    using namespace std;
    
    int main() {
    	vector<int> arr{ 4,7,2,9,5,0,8,1,6,3 };
    
    	sort(arr.begin(), arr.end());
    
    	for (int i = 0; i < 10; i++) {
    		cout << arr[i] << " ";
    	}
    
    	cout << endl;
    
    	sort(arr.begin(), arr.end(), greater<int>()); 
    
    	for (int i = 0; i < 10; i++) {
    		cout << arr[i] << " ";
    	}
    
    	return 0;
    }

    💾 [예제 3 : compare 함수를 통해 구조체 정렬하기]

    더보기
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<string>
    using namespace std;
    
    typedef struct {
    	string name;
    	int age;
    }person;
    
    //이름을 사전순으로 정렬하되, 이름이 같으면 나이가 적은 순서로 정렬
    bool compare_1(person a, person b) {
    	if (a.name == b.name)
    		return a.age < b.age; // 2.이름이 같으면, 나이가 적은 순으로 정렬
    	else 
    		return a.name < b.name; // 1.이름을 사전순으로 정렬
    }
    
    //나이가 적은 순서로 정렬하되, 나이가 같으면 이름을 사전순으로 정렬
    bool compare_2(person a, person b) {
    	if (a.age == b.age) // 2.나이가 같으면 이름을 사전순으로 정렬
    		return a.name < b.name;
    	else
    		return a.age < b.age; // 1.나이가 적은 순서로 정렬
    }
    
    int main() {
    	
    	vector<person> arr;
    
    	arr.push_back({ "eee", 15});
    	arr.push_back({ "ccc", 4 });
    	arr.push_back({ "eee", 1 });
    	arr.push_back({ "bbb", 3 });
    	arr.push_back({ "ccc", 7 });
    	arr.push_back({ "aaa", 2 });
    	arr.push_back({ "fff", 1 });
    	arr.push_back({ "eee", 7 });
    	
    	
    	sort(arr.begin(), arr.end(), compare_1);
    
    	puts("compare_1");
    
    	for (int i = 0; i < arr.size(); i++) {
    		cout << arr[i].name << " ";
    		cout << arr[i].age << endl;
    	}
    
    	puts(" ");
    	puts("compare_2");
    
    	sort(arr.begin(), arr.end(), compare_2);
    
    	for (int i = 0; i < arr.size(); i++) {
    		cout << arr[i].name << " ";
    		cout << arr[i].age << endl;
    	}
    
    	return 0;
    }

    👀 결과

    예제3 결과


    min, max

    • min, max를 사용해 최대, 최소값을 구할 수 있다.
    • 두 개의 원소에 대해서만 가능, 3개하고 싶으면 min(a, min(b,c)); 이렇게하면 된다.

    [예제 1 : a, b 중 최대, 최소 구하기]

    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int main() {
    	int a = -9999, b = 9999;
    	int res;
    
    	res = min(a, b);
    	cout << res << endl;
    
    	res = max(a, b);
    	cout << res << endl;
    
    	return 0;
    }

    swap 

    • 두 원소의 값을 교환한다. 
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    int main() {
    	int a = 2, b = 5;
    
    	swap(a, b);
    	cout << a << endl;
    	cout << b << endl;
    
    	return 0;
    }

    C++ 표준 템플릿 라이브러리(STL : Standard Template Library)

    • c++ 표준 라이브러리는 꽤 많은 종류의 라이브러리들이 있다. (iostream, chrono, regex)
    • 하지만 보통 C++ 템플릿 라이브러리(STL)을 일컫는다면, 아래와 같은 3개의 라이브러리를 의미한다.
    • 임의 타입의 객체를 보관할 수 있는 컨테이너(container)
    • 컨테이너에 보관된 원소에 접근할 수 있는 반복자(iterator)
    • 반복자들을 가지로 일련의 작업을 수행하는 알고리즘(algorithm)
    • 반복자는 컨테이너 원소에 접근할 수 있는 포인터와 같은 객체이다. 

    반복자(iterator)

    반복자(iterator)란 STL 컨테이너에 저장된 요소를 반복적으로 순회하여, 각각의 요소에 대한 접근을 제공하는 객체입니다.

    즉, 컨테이너의 구조나 요소의 타입과는 상관없이 컨테이너에 저장된 데이터를 순회하는 과정을 일반화한 표현입니다.

    템플릿이 타입과 상관없이 알고리즘을 표현할 수 있게 해준다면, 반복자는 컨테이너와 상관없이 알고리즘을 표현할 수 있게 해주는 것입니다.

    반복자가 가져야 할 요구 사항과 정의되어야 할 연산자는 다음과 같습니다.

    1. 가리키는 요소의 값에 접근할 수 있어야 합니다. 따라서 참조 연산자(*)가 정의되어야 합니다.

    2. 반복자 사이의 대입 연산, 비교 연산이 가능해야 합니다. 따라서 대입, 관계 연산자가 정의되어야 합니다.

    3. 가리키는 요소의 주변 요소로 이동할 수 있어야 합니다. 따라서 증가 연산자(++)가 정의되어야 합니다.

    위와 같은 요구 사항을 모두 갖춰야만 STL 알고리즘에서 반복자로 사용될 수 있습니다.

     

    순차 컨테이너(Sequence Container)

    • 순차 컨테이너는 배열 처럼 객체를 순차적으로 보관한다.
    • vector, deque, list 등이 있다.

    vector  

    • 가변 길이 배열이다. <vector>에 정의되어 있다.
    • 원소들이 메모리 상에 실제로 순차적으로 저장되어 있다.
    • 따라서 임의의 위치에 있는 원소에 접근하는 것을 매우 빠르게 수행할 수 있다.
    • [ ] 을 통해 임의의 위치 원소에 접근할 수 있다. 
    • size : vector의 사이즈를 리턴한다. 
    • push_back : 맨 뒤에 원소를 추가한다.
    • pop_back : 맨 뒤의 원소를 제거한다.
    • insert : 임의의 위치에 원소를 추가한다.
    • erase : 임의의 위치의 원소를 제거한다.
    • begin : vector의 첫번째 원소를 가리키는 반복자를 리턴한다.
    • end : vector의 마지막원소 한 칸 뒤를 가리키는 반복자를 리턴한다. 
    • clear : 원소를 모두 제거한다. 

    vector 기본예제

    #include<iostream>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    int main() {
    	vector<int> arr;
    
    	//맨뒤에 원소 추가
    	arr.push_back(1);
    	arr.push_back(2);
    	arr.push_back(3);
    
    	//배열처럼 임의 원소에 O(1)로 접근 가능
    	printf("%d %d %d %d\n", arr.size(), arr[0], arr[1], arr[2]);
    
    	//맨뒤의 원소 제거
    	arr.pop_back();
    	arr.pop_back();
    	arr.pop_back();
    
    	//벡터 사이즈 출력
    	printf("%d\n", arr.size());
    
    	arr.push_back(1);
    	arr.push_back(3);
    	arr.push_back(5);
    	arr.push_back(6);
    	arr.push_back(7);
    
    	//임의 위치에 데이터 추가
    	arr.insert(arr.begin() + 1, 2); // arr[1]위치에 2를 넣는다. arr[1]은 뒤로 밀림
    	arr.insert(arr.begin() + 3, 4); // arr[3]위치에 4를 넣는다. arr[3]은 뒤로 밀림
    
    	//임의 위치의 데이터 제거
    	arr.erase(arr.begin() + 5);
    	arr.erase(arr.begin() + 5);
    
    	for (int i = 0; i < arr.size(); i++) {
    		printf("%d ", arr[i]);
    	}
    	puts("");
    
    	// iterator 활용
    	sort(arr.begin(), arr.end(), greater<int>());
    
    	for (int i = 0; i < arr.size(); i++) {
    		printf("%d ", arr[i]);
    	}
    	cout << endl;
    
    	//모든 원소 삭제
    	arr.clear();
    	printf("\n after clear, arr size = %d\n", arr.size());
    
    	// 1차원 vector 초기화 : 크기 10의 벡터를 만들고 5로 초기화
    	vector<int> v1(10, 5);
    	//vector<int> v = vector<int>(10, 7); //이와 같이 초기화할 수 있다.
    
    	for (int i = 0; i < 10; i++) {
    		cout << v1[i];
    	}
    
    	cout << endl;
    	cout << endl;
    
    	// 2차원 vector 초기화 : 크기 10x10의 벡터를 만들고 7로 초기화
    	vector<vector<int>> v2(10, vector<int>(10, 7));
    
    	for (int i = 0; i < 10; i++) {
    		for (int j = 0; j < 10; j++) {
    			cout << v2[i][j];
    		}
    		cout << endl;
    	}
    
    	return 0;
    }

    vector 초기화 예제

    #include <vector>
    #include <iostream>
    using namespace std;
    
    int main() {
    	vector<int> arr1(5); // 원소 5개를 만들고 0으로 초기화한다. 
    
    	for (int i = 0; i < arr1.size(); i++) {
    		cout << arr1[i];
    	}
    
    	cout << endl;
    	cout << endl;
    
    	vector<int> arr2(7, 7);
    
    	for (int i = 0; i < arr2.size(); i++) {
    		cout << arr2[i];
    	}
    
    	cout << endl;
    	cout << endl;
    
    	vector<vector<string>> arr3(5, vector<string>(4, "abcd")); // 복잡한 vector 초기화
    
    	for (int i = 0; i < arr3.size(); i++) {
    		for (int j = 0; j < arr3[i].size(); j++) {
    			cout << arr3[i][j][0] <<" " << arr3[i][j][1] << " " << arr3[i][j][2] << " " << arr3[i][j][3] << endl;
    		}
    		cout << endl;
    	}
    
    	return 0;
    }

    deque

    • 양쪽에서 끝나는 큐(double ended queue)로 <deque>에 정의되어 있다.
    • 다른 순차 컨테이너처럼 deque도 선형으로 메모리 상에 위치한다. 하지만 vector와 달리 deque는 모든 원소가 메모리 상에 연속적으로 존재한다고 보장할 수 없다. vector는 capacity가 꽉 찼을 경우 새롭게 크게 한 덩어리의 메모리를 할당하지만, deque는 메모리 상에서 잘게 쪼개서 보관한다. vector에 비해 조금 복잡하지만 메모리 공간을 효율적으로 사용할 수 있다. 
    • begin : 첫번째 원소를 가리키는 반복자를 리턴한다.
    • end : 끝 부분을 가리키는 반복자를 리턴한다.
    • size : deque의 현재 원소의 개수를 리턴한다.
    • empty : deque이 비어있는지 체크한다. 
    • front : 첫 번째 원소에 접근한다.
    • back : 마지막 원소에 접근한다.
    • push_back : 원소를 끝에 추가한다.
    • push_front : 원소를 맨 앞에 추가한다.
    • pop_back : 마지막 원소를 제거한다.
    • pop_front : 첫 번째 원소를 제거한다.
    • erase : 원소를 제거한다.
    • clear : 원소를 모두 제거한다.
    • [ ] 을 통해 임의의 위치 원소에 접근할 수 있다.
    #include<iostream>
    #include<deque>
    #include<algorithm>
    using namespace std;
    
    int main() {
    	
    	deque<int> dq;
    
    	dq.push_back(3);
    	dq.push_back(4);
    	dq.push_front(2);
    	dq.push_front(1);
    
    	while (!dq.empty()) {
    		printf("%d ", dq.front());
    		dq.pop_front();
    	}
    
    	puts("");
    
    	dq.push_back(1);
    	dq.push_back(2); 
    	dq.push_back(3);
    	dq.push_back(4);
    
    	while (!dq.empty()) {
    		printf("%d ", dq.back());
    		dq.pop_back();
    	}
    
    	puts("");
    
    	dq.push_back(1);
    	dq.push_back(2);
    	dq.push_back(3);
    	dq.push_back(4);
    
    	printf("deque size = %d\n", dq.size());
    
    	dq.clear();
    
    	printf("after clear, deque size = %d\n", dq.size());
    
    	return 0;
    }

    list

    • [ ] 접근 불가능

    컨테이너 어댑터(Container Adaptor)

    ◾ 컨테이너 어댑터는 반복자(iterator)를 지원하지 않는다.

    stack

    • LIFO(Last In First Out), <stack>에 정의
    • push : stack push
    • pop : stack pop
    • top : 가장 위에 있는 원소를 가져온다.
    • empty : stack이 비어있으면 true 그렇지 않으면 false 반환
    • size : stack의 원소수 반환
    • 참고 : stack이 empty일 때, stack.top() 하면 런타임 오류남(empty 체크 먼저 해야함)
    #include<iostream>
    #include<stack>
    using namespace std;
    
    int main() {
    	stack<int> st;
    
    	st.push(1);
    	st.push(2);
    	st.push(3);
    	st.push(4);
    
    	while (!st.empty()){
    		printf("스택 사이즈 : %d, pop한 원소 : %d\n",st.size(), st.top());
    		st.pop();
    	}
    
    	return 0;
    }
    

    queue

    • FIFO(First In First Out), queue<int>에 정의
    • push : enqueue
    • pop : dequeue
    • front : 가장 앞에 있는 원소 반환
    • back : 가장 뒤에 있는 원소 반환
    • empty : queue가 비어있으면 true 아니면 false 반환
    • size : queue 사이즈를 반환
    #include<iostream>
    #include<queue>
    using namespace std;
    
    int main() {
    	queue<int> q;
    
    	q.push(1);
    	q.push(2);
    	q.push(3);
    	q.push(4);
    
    	printf("q.size() : %d, q.front() : %d, q.back() : %d\n",q.size(), q.front(), q.back());
    
    	q.pop();
    	q.pop();
    
    	printf("q.size() : %d, q.front() : %d, q.back() : %d\n", q.size(), q.front(), q.back());
    
    	q.pop();
    	q.pop();
    
    	if (q.empty())
    		printf("큐가 비어있습니다.");
    
    	return 0;
    }

    priority_queue

    • defalut는 max heap이다.
    • min heap 쓰고 싶다면, 값을 음수로 바꿔서 넣어준다. https://koosaga.com/9
    • 우선순위 큐는 실제로는 priority_queue<자료형, 구현체, 비교 연산자>로 정의하는 것을 알 수 있다.
    • 자료형은 int, double, 선언한 클래스 
    • 구현체는 기본적으로 vector<자료형>으로 정의
    • 비교 연산자는 기본적으로 less<자료형>으로 정의된다(MAX )
    • 비교 연산자를 greater<자료형> 으로 정의하면, min heap이 된다.
    • Pair 힙에 넣으면 first, second 순으로 힙이 작동한다.

     


    ✔️ 연관컨테이너

    ◾ 연관 컨테이너는 순차 컨테이너와는 다르게 키(key) - 값(value) 구조를 가진다.

    ◾ 특정한 키를 통해 대응되는 값을 얻을 수 있다.

    ◾ 중복된 원소(키)를 허용하지 않는다. 

    ◾ Set과 Map은 내부적으로 BST(Red-Black Tree)로 구현되어있기 때문에 O(logN) 시간에 키에 접근할 수 있다. 

    ◾ Set과 Map은 앞서 말했듯이 Red-Black Tree로 구현 되었기에 삽입, 삭제 연산에서 상당히 많은 작업이 발생할 수 있으므로 시간 복잡도 증가에 유의 해야한다. 

    1️⃣ Set 

    ◾ 특정 키가 연관 컨테이너에 존재하는지 유무를 알 수 있다.

    ◾ Set은 키만 보관하고 키의 존재 여부를 알 수 있다.

    💾 Set.cpp

    더보기
    #include<iostream>
    #include<set>
    using namespace std;
    
    int main() {
    	set<int> s;
    
    	s.insert(1);
    	s.insert(2);
    	s.insert(3);
    	s.insert(4);
    
    	cout << "1이 셋에 존재해? :  " << s.count(1) << endl; // 1의 개수 반환(0아니면 1)
    	cout << "2가 셋에 존재해? :  " << s.count(2) << endl;
    	cout << "3이 셋에 존재해? :  " << s.count(3) << endl;
    	cout << "4가 셋에 존재해? :  " << s.count(4) << endl;
    	cout << "5가 셋에 존재해? :  " << s.count(5) << endl;
    	
    	puts("");
    	puts("이터레이터를 통한 모든 원소 조회");
    	for (auto it = s.begin(); it != s.end(); it++)
    		cout << *it << endl;
    
    	return 0;
    }

     


    2️⃣ map

    ◾  key와 value로 구성되어있다.

    ◾ 특정 키에 대응 되는 값이 무엇인지 알 수 있다. 

    💾 map.cpp

    더보기
    #include<iostream>
    #include<string>
    #include<map>
    using namespace std;
    
    int main() {
    	map<string, int> m;
    
    	m.insert({ "박병욱", 26 });
    	m.insert({ "김규식", 24 });
    	m.insert({ "이기택", 28 });
    	m.insert({ "이기택", 25 }); // map은 중복된 원소를 허락하지 않는다. 왼쪽 코드는 무시됨. 
    
    	//아래와 같이 배열 형태로 원소를 추가할 수 있다.
    	/*
    	m["박병욱"] = 26;
    	m["김규식"] = 24;
    	m["이기택"] = 28;
    	*/
    
    	/*count는 원소의 유무를 알려준다. 1 또는 0 반환*/
    	cout << m.count("박병욱") << endl;
    	cout << m.count("김규식") << endl;
    	cout << m.count("이기택") << endl;
    
    	//operator [] 연산은 key가 없을 경우 map에 {key: default} 값이 "삽입"된다.
    	/*
    	cout << m["박병욱"] << endl;
    	cout << m["김규식"] << endl;
    	cout << m["이기택"] << endl;
    	*/
    	
    	//find는 key가 없을 경우 map에 데이터를 삽입하지 않음.
    	cout << m.find("박병욱")->second << endl;
    	cout << m.find("김규식")->second << endl;
    	cout << m.find("이기택")->second << endl;
    	
    
    	//이터레이터를 통해 map을 아래와 같이 조회할 수 있다. (키 기준 오름차순 출력)
    	for (auto it = m.begin(); it != m.end(); it++) {
    		cout << it->first << " " << it->second << endl;
    	}
        
        //이터레이터를 통해 map을 아래와 같이 조회할 수 있다. (키 기준 내림차순 출력)
        for(auto it = m.rbegin(); it != m.rend(); it++){
          	cout << it->first << " " << it->second << endl;
        }
    
    	return 0;
    }

     

     


    문자열

    substr, replace

    • <string>에 정의되어있다.
    • size(), length() : string의 길이를 반환한다.
    • clear(), : 스트링을 지운다.
    • substr(index, len) : index부터 len만큼 잘라서 반환한다.
    • replace(시작주소, len, '문자열1')  : 시작주소부터 len길이까지의 범위를 '문자열1' 로 대체한다.
    #include<iostream>
    #include<string>
    
    using namespace std;
    
    int main() {
    	string s1 = "hello world!";
    	string s2 = "HELLO world!";
    
    	cout << s1.substr(0, 5) << endl; // index 0부터 길이 5만큼 자른다.
    	cout << s1.substr(6) << endl; // index 6부터 끝까지 자른다. 
    
    	s1.replace(0, 5, "HELLO"); // index 0부터 길이 5만큼 "HELLO" 문자열로 대체한다.
    
    	cout << s1 << endl;
    
    	if (s1.compare(s2) == 0) // 문자열 s1과 s2를 비교한다. 
    		cout << "s1, s2 same";
    
    	return 0;
    }

    한글을 잘라보자. (영어는 1바이트 한글은 2바이트이므로 고려해서 잘라줘야함.)

    #include<iostream>
    #include<string>
    using namespace std;
    
    int main() {
    
    	string str = "대한민국";
    	cout << str.substr(0, 2) << endl;
    	cout << str.substr(2, 2) << endl;
    	cout << str.substr(4, 2) << endl;
    	cout << str.substr(6, 2) << endl;
    
    }

    compare

    • compare('비교할 문자열') : '비교할 문자열'과 비교해서 같으면 0, 다르면 사전상 순서에 따라 -1 또는 1을 반환한다.   
    #include<iostream>
    #include<string>
    using namespace std;
    
    int main() {
    	string a = "abcd";
    	string b = "efgh";
    
    	if (a.compare(b) == 0) {
    		cout << "두 문자열은 같습니다.";
    	} else if (a.compare(b) < 0) {
    		cout << "a가 b보다 사전순으로 앞 입니다.";
    	}else if (a.compare(b) > 0) {
    		cout << "a가 b보다 사전순으로 뒤 입니다.";
    	}
    
    	return 0;
    }

    stoi 

    • <string>에 정의되어있다.
    • string을 int 형으로 바꿔준다.
    • c++ 11부터 가능하다.
    #include<iostream>
    #include<string>
    using namespace std;
    
    int main() {
    	string str = "123";
    	int num;
    
    	num = stoi(str);
    	cout << num;
    
    	return 0;
    }

    substr

    ◾ 문자열의 일부를 반환한다. 

     substr(첫 번째 문자열의 인덱스, 부분 문자열의 길이)

    #include<iostream>
    #include<string>
    using namespace std;
    
    int main() {
    	string str = "ABCDEFG";
    
    	cout << str.substr(1) << endl; //1번 인덱스부터 끝까지 자른다.
    	cout << str.substr(3) << endl; //3번 인덱스부터 끝까지 자른다.
    	cout << str.substr(1, 2) << endl; //1번 인덱스부터 2개만큼 자른다. 
    	cout << str.substr(1, 3) << endl;
    	cout << str.substr(1, 4) << endl;
    	cout << str.substr(1, 5) << endl;
    	cout << str.substr(2, 4) << endl;//2번 인덱스부터 4개만큼 자른다. 
    	cout << str.substr(3, 2) << endl;
    	cout << str << endl;
    
    	return 0;
    }

    to_string

    • <string>에 정의되어있다.
    • int를 string으로 바꿔준다.

    isdigit

    문자숫자라면 1반환

    아니라면 0반환

     

    tolower, toupper 

    ◾ tolower(c); : 문자 c를 소문자로 바꾼다.

    ◾ toupper(c); : 문자 c를 대문자로 바꾼다.

    #include<string>
    #include<iostream>
    using namespace std;
    
    
    int main() {
    	string str1 = "ABCDE";
    	string str2 = "abcde";
    
    	for (int i = 0; i < str1.size(); i++) {
    		str1[i] = tolower(str1[i]);
    	}
    
    	cout << str1 << endl;
    
    	for (int i = 0; i < str1.size(); i++) {
    		str2[i] = toupper(str2[i]);
    	}
    
    	cout << str2 << endl;
    
    	return 0;
    }

    istringstream 

     istringstream을 사용하여 공백을 기준으로 문자열을 자를 수 있다. 

    #include<iostream>
    #include<sstream>
    
    using namespace std;
    
    int main() {
    	string str1 = "동해물과 백두산이 마르고 닳도록";
    
    	istringstream iss(str1);
    
    	string a, b, c, d;
    
    	iss >> a;
    	iss >> b;
    	iss >> c;
    	iss >> d;
    
    	cout << a << " " << b << " " << c << " " << d << endl;
    
    	return 0;
    }

    find

    문자열에서 원하는 문자열의 위치를 찾는다.

    원하는 문자열이 없으면 npos를 리턴한다.nposstring::npos로 정의되는 상수 이다.

    #include<iostream>
    using namespace std;
    
    int main() {
    	string str = "hello beautiful world";
    
    	// 문자열을 찾는데 성공하였다면, 해당 문자열의 시작 위치를 반환한다.
    	cout << str.find("hello") << endl;
    	cout << str.find("beautiful") << endl;
    	cout << str.find("world") << endl;
    
    	// 문자열을 찾지 못한다면 npos 를 리턴한다.
    	// npos 는 string::npos로 정의되는 상수이다.
    	cout << str.find("bad") << endl;
    
    	if (str.find("bad") == string::npos)
    		cout << "찾으시는 문자열이 없어요." << endl;
    
    	return 0;
    }

     


    그 외 라이브러리들

     

    accumulate <numeric>

    • accumulate(arr.begin(), arr.end(), 0) // 컨테이너의 합을 구해준다. 0은 초기값.

    memset - <cstring>

    • 특정 범위를 어떤 값으로 채운다.
    • memset(시작주소, 값, 채울 구조의 사이즈);
    • memset은 byte 단위로 동작된다. 따라서 0, char 등 1byte 단위로만 초기화가 가능하다.

    distance

    ◾ 두 반복자의 거리를 반환해준다.

    #include<vector>
    #include<iostream>
    using namespace std;
    
    int main() {
    	vector<int> v(5, 1);
    
    	cout << distance(v.begin(), v.end()); //5
        cout << distance(v.begin()+2, v.end()); //3
    
    	return 0;
    }

    lower_bound

     lower_bound(begin(), end(), value)

     [ begin(), end() ) 범위에서 value 이상의 값이 처음 나타나는 위치를 반환한다.

    ◾ 이진탐색으로 구현되어있다. O(logN)

     

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    int main() {
    
    	vector<int> v{ 1,2,3,4,5,10,9,8,7,6 };
    
    	sort(v.begin(), v.end());
    
    	vector<int>::iterator it = lower_bound(v.begin(), v.end(), 3); // 3이상이 나타나는 최초 위치 반환
    	cout << *it;
    
    	return 0;
    }

    upper_bound

    upper_bound(begin(), end(), value)

     [ begin(), end() ) 범위에서 value 초과의 값이 처음 나타나는 위치를 반환한다.

    ◾ 이진탐색으로 구현되어있다. O(logN)

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    int main() {
    
    	vector<int> v{ 1,2,3,4,5,10,9,8,7,6 };
    
    	sort(v.begin(), v.end());
    
    	vector<int>::iterator it = upper_bound(v.begin(), v.end(), 3); // 3보다 큰 값이 나타나는 최초 위치 반환
    	cout << *it;
    
    	return 0;
    }

     


    ✔️ C 표준 라이브러리

    c  : <math.h>, c++ : <cmath>

     

     

    #include<cmath>
    #include<iostream>
    using namespace std;
    
    int main() {
    	int a = 2, b = 16, c = 32, d = 7;
    
    	cout << pow(a, 1) << endl;//2
    	cout << pow(a, 2) << endl;//4
    	cout << pow(a, 3) << endl;//8
    	cout << pow(a, 4) << endl;//16
    	cout << pow(a, 10) << endl;//1024
    	cout << pow(b, 2) << endl;//256
    	cout << pow(c, 2) << endl;//1024
    	cout << pow(d, 2) << endl;//49
    
    	return 0;
    }

     

     sqrt(n) : 루트 n을 반환한다. 

    #include<cmath>
    #include<iostream>
    using namespace std;
    
    int main() {
    	int a = 2, b = 16, c = 32;
    
    	cout << sqrt(a) << endl; //1.14121
    	cout << sqrt(b) << endl; //4
    	cout << sqrt(c) << endl; //5.65685
    
    	return 0;
    }

    ✔️ cin, cout 속도 빠르게 하기

     scanf, printf와 함께 사용하면 안된다.

    싱글 쓰레드 환경에서만 사용 가능하다.

    #include<cmath>
    #include<iostream>
    using namespace std;
    
    int main() {
    	ios_base :: sync_with_stdio(false);
    	cin.tie(NULL); 
    	cout.tie(NULL);
        
        int num;
        
        for(int i=0; i<100000; i++){
        	cin>>num;
            cout<<num;
        }
    
    	return 0;
    }

     

    참고

    https://modoocode.com/

    댓글

Designed by Tistory.