<aside>
<aside>
정수 → 문자열 변환(to_string)을 고려하는 경우
#include <iostream>
#include <string> //to_string, stoll ...
#include <algorithm>
int main() {
long long n = 14275;
std::string s = std::to_string(n); // "14275"
// 각 자리 출력 or 각 자리수 합
int sum = 0;
for(char c : s){
std::cout << c << " "; // 1 4 2 7 5
sum += (c - '0'); // // '0' = 48 ASCII
}
//자리수 뒤집기 or 팰린드롬 검사
std::string r = s;
std::reverse(r.begin(), r.end()); // "57241"
bool isPalindrome = (s == r); // false
long long rev = std::stoll(r); // 숫자로 다시 변환 가능 //string to long long
std::string a = "100000000000000000000";
std::string b = "99999999999999999999";
// long long으로 표현할 수 있는 (약 9×10^18)을 넘어간 수끼리 비교
if(a.length() > b.length()){
std::cout << "a is bigger\n";
}else if(a.length() < b.length()){
std::cout << "b is bigger\n";
}else if(a > b){ // 자리수 같으면 사전순 비교
std::cout << "a is bigger\n";
}else {
std::cout << "b is bigger\n";
}
return 0;
}
<algorithm>
컨테이너(vector, array, string 등)에 대해 정렬, 탐색, 변형을 해주는 함수들이 모여 있음
STL 컨테이너와 함께 사용
코테 중요 패턴 ⭐⭐⭐⭐⭐
// AlgorithmExamples.cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main(){
std::vector<int> v = {5,2,4,1,3,3,2,1};
// 코테 중요 패턴 1. unique (중복 제거 패턴) - 인접 중복만 제거 가능
std::vector<int> v3 = v;
std::sort(v3.begin(),v3.end()); //1 1 2 2 3 3 4 5
v3.erase(std::unique(v3.begin(),v3.end()), v3.end());
//std::unique(v3.begin(),v3.end()) => 중복 제거 후 새 logical end iterator 반환
//1 2 3 4 5 ? ? ?
//v3.erase(새로운 end, end()); => 논리적으로 필요 없는 뒤쪽 제거
//1 2 3 4 5
std::cout<<"//1. unique\n";
for(int x:v3) std::cout<<x<<" ";
std::cout<<"\n\n";
// 코테 중요 패턴 2. upper_bound, lower_bound
std::vector<int> v4 = {1,2,3,3,3,4,5}; //정렬된 상태여야함
auto lb = std::lower_bound(v4.begin(), v4.end(), 3);
auto ub = std::upper_bound(v4.begin(), v4.end(), 3);
/*
lb == 3 이상이 처음 나오는 위치 == index 2 가리키는 iterator 반환
ub == 3 초과가 처음 나오는 위치 == index 5 가리키는 iterator 반환
ub - lb == 3의 개수
1 2 3 3 3 4 5
↑ ↑
lb ub
*/
std::cout<<"//2-1. lower_bound: ";
std::cout<<"index: "<<lb - v4.begin()<<"\n\n";
std::cout<<"//2-2. upper_bound: ";
std::cout<<"index: "<<ub - v4.begin()<<"\n\n";
// 코테 중요 패턴 3. next_permutation (사전순 다음 순열)
std::vector<int> p = {1,2,3}; //// 전체 순열 생성하려면 반드시 오름차순 시작
std::cout<<"//3. next_permutation\n";
do{
for(int x:p) std::cout<<x<<" ";
std::cout<<"\n";
}while(std::next_permutation(p.begin(),p.end()));
//조건식 뜻 : 사전순 다음 순열이 존재한다면.
//p 안에서 숫자 자리 바뀜
/*
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1 //내림차순 형태 -> 다음 순열 없음(끝)
오름차순이어야 모든 순열 6개 생성됨
*/
std::vector<int> q = {2,1,3};
// 이렇게 하면 2 1 3 이후 4개만 나옴
std::cout<<"\n";
return 0;
}
대표함수
참고>> **.end()**는 마지막 원소 “**다음 위치”**를 가리키는 반복자 반환 ⭐⭐⭐⭐⭐
| 함수 | 설명 | ||
|---|---|---|---|
sort() |
정렬 | std::sort(v.begin(), v.end()); //기본 |
//내림차순 1
std::sort(v.begin(), v.end(), std::greater<char>());
//내림차순 2
sort(s.rbegin(), s.rend()); | • 오름차순 정렬
• O(N log N)
• 두 번째 인자 전까지 sorting |
| find() | 값 찾기 | auto it = std::find(v.begin(), v.end(), 3);
auto it= std::find(s.begin(), s.end(), 'w');
int index = it - v.begin(); | • 3을 찾으면 iterator 반환
• 없으면 v.end() |
| find_if() | 조건에 맞는 값 찾기 | // 첫 번째 숫자 문자의 위치
auto it = find_if(s.begin(), s.end(), ::isdigit); | |
| binary_search() | 이진탐색 | // 반드시 정렬되어 있을 것 (기본: 오른차순)
bool found = std::binary_search(v.begin(), v.end(), 7);
// 내림차순 정렬된 벡터 desc 이면, 반드시 같은 비교자를 넘겨줘야 함
bool found = std::binary_search(desc.begin(), desc.end(), 7, std::greater<int>()); | • bool 반환 |
| lower_bound
upper_bound ⭐ | lb = ‘이상’
ub = ‘초과’ | auto lb = std::lower_bound(v4.begin(), v4.end(), 3);
auto ub = std::upper_bound(v4.begin(), v4.end(), 3);
//ub - lb == 3의 개수 | • 정렬된 상태여야 함
• iterator 반환 |
| unique ⭐(위 예시코드 참고) | 중복제거 | std::sort(v.begin(), v.end()); //sorting 필요
auto it = std::unique(v.begin(),v.end()); //앞당기기
v.erase(it, v.end()); //새로운 end()인 it부터 뒤는 쭉 날리기 | • 정렬된 상태여야 함
• 새 끝 iterator 반환
• 진짜 삭제가 아니고 앞당기기이므로 .erase()와 함께 사용 |
| remove() | 값 제외하고 앞당기기 | auto it = std::remove(v.begin(), v.end(), 3) //3빼고 앞당기기
v.erase(it, v.end()); //새로운 end()인 it부터 뒤는 쭉 날리기 | • 지워질 요소를 뒤로 몰아놓고 새 logical end를 반환
• 진짜 삭제가 아니고 앞당기기이므로 .erase()와 함께 사용 |
| remove_if() | | s.erase(remove_if(s.begin(), s.end(), ::isspace), s.end());
//cctype 함수 ::isspace | |
| binary_search() | | bool exist = std::binary_search(v.begin(), v.end(), 4); | |
| reverse() | 뒤집기 | std::reverse(v.begin(), v.end()); | |
| swap() | | std::swap(v[i], v[j]); | |
| max() min() | 최대/최소 | std::max(3,7) | • 값 반환 |
| max_element min_element | 최대/최소 | auto it = std::max_element(v.begin(), v.end())
//*max_element(...)로 값 접근 | • iterator 반환 |
| count() | 개수 세기 | int c = std::count(v.begin(), v.end(), 2); | • 원소 2의 개수 |
| count_if() | 조건에 맞는 값 개수 세기 | int upperCnt = count_if(s.begin(), s.end(), ::isupper);
//cctype 함수 ::isupper | |
| copy() | 원본 범위를 목적지로 복사 | std::copy(a.begin(), a.end(), b.begin()); | • 범위 설정 가능
• 목적지 크기 미리 확보 필요 |
| fill() | 범위를 같은 값으로 채움 | std::fill(v.begin(), v.end(), 7); | |
| rotate | 제자리 회전 | std::rotate(first, middle, last);
before: [A, B, C, D, E]
std::rotate(begin, begin+2, end)
after: [C, D, E, A, B] | • middle이 새로운 첫 번째 원소가 되도록 범위를 회전 |
| next_permutation ⭐ | 사전순 다음 순열 | std::next_permutation(p.begin(),p.end()) | • 전체 경우를 모두 보려면, 사전 오름차순 sorting 필수
• 시작용으로 iota 많이 사용 |
| transform | 변환 | std::transform(src.begin(), src.end(), dst.begin(), 함수);
//범위에 해당하는 부분에 함수처리해서 목표 위치에 출력
std::transform( str.begin(), str.end(), str.begin(), std::toupper //cctype 함수 ); //원본 덮어쓰기 가능 //문자열 대문자 변환 //문자열 소문자 변환에서는 std::tolower
⇒ 근데 위 경우에서는 오버로딩이 여러개라 컴파일 에러남.
일반 함수에서는 가장 비슷한 인자를 찾아 오버로드를 해결하지만, toupper는 함수 포인터이기 때문에 해결 불가능
→ 람다나 함수 객체로 감싸기!! | • 1~2번째 인자 → 변환할 범위 [begin, end)
• 3번째 인자 → 변환 결과 저장 위치
• 4번째 인자 → 적용할 함수(::toupper) |
lambda //즉석 익명 함수
#include <string>
#include <vector>
#include <algorithm>
// std::sort 예시
// n번째 char로 오름차순 정렬하는데, 같으면 사전식 오름차순하는 sorting
// [capture] (parameter) -> return_type { body }
// [capture] (parameter) { body } // 리턴타입은 컴파일러가 return 문을 보고 자동 추론
std::vector<std::string> solution(std::vector<std::string> strings, int n) {
std::sort(
strings.begin(),
strings.end(),
[&n](std::string a, std::string b) //바깥변수 n을 볼 수 있도록
{
if(a[n] == b[n]){
return a < b; //bool 반환
}
return a[n] < b[n]; //bool 반환
}
);
return strings;
}
// std::transform 예시
// [capture] (parameter) -> return_type { body } // 익명 함수
#include <string>
#include <vector>
#include <algorithm>
#include <cctype> //::toupper()
std::vector<int> src = {1, 2, 3, 4};
std::vector<int> dst(src.size()); //사이즈 미리 지정해주기
std::transform(
src.begin(),
src.end(),
dst.begin(),
[](int x) { return x * 2; }
);
//대문자 변환 안전 ver.
std::transform(
s.begin(),
s.end(),
s.begin(),
[](unsigned char c) //UB(Undefined Behavior) 방지용, 양수만 받기
{
return std::toupper(c); //int toupper(int ch); 이어서 UB 발생 가능
}
);
// std::count_if 예시
// 'a' 이상 'e' 이하인 문자 개수
int cnt = std::count_if(s.begin(), s.end(),
[](char c){ return c >= 'a' && c <= 'e'; });
<cmath>
실수 계산 라이브러리
인자값과 반환값 모두 double 타입
대표함수
| 함수 | 설명 | ||
|---|---|---|---|
sqrt() |
제곱근 | long long x = std::sqrt(n) + 0.5; | • 부동소수점 오차 주의 필요 |
• 0.5 더하거나, if문으로 점검 |
| abs() | 절댓값 | | |
| ceil() | 올림 | | |
| floor() | 내림 | std::floor(3.7) == 3 | |
| round() | 반올림 | | |
| pow() | 거듭제곱 | int x = round(std::pow(3,4));
int y = (int)(std::pow(3,4) + 0.5); | • 부동소수점 오차 주의 필요 |
| sin(), cos() | 사인, 코사인 | | |
| log() | 자연로그 | | |
</aside>
<aside>
**객체지향 프로그래밍 (**Object-Oriented Programming)
<aside>
</aside>
<aside>
</aside>
<aside>
</aside>