<aside>
<aside>
정수 → 문자열 변환(to_string)을 고려하는 경우
#include <iostream>
#include <string>
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); | |
| 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()); | |
| max() min() | 최대/최소 | std::max(3,7) | • 값 반환 |
| max_element min_element | 최대/최소 | auto it = std::max_element(v.begin(), v.end())
//*max_element(...)로 값 접근 | • iterator 반환 |
| 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 반환 |
| count() | 개수 세기 | int c = std::count(v.begin(), v.end(), 2); | • 원소 2의 개수 |
| count_if() | 조건에 맞는 값 개수 세기 | int upperCnt = count_if(s.begin(), s.end(), ::isupper); | |
| copy() | 원본 범위를 목적지로 복사 | std::copy(a.begin(), a.end(), b.begin()); | • 범위 설정 가능
• 목적지 크기 미리 확보 필요 |
| fill() | 범위를 같은 값으로 채움 | std::fill(v.begin(), v.end(), 7); | |
| next_permutation ⭐ | 사전순 다음 순열 | std::next_permutation(p.begin(),p.end()) | • 전체 경우를 모두 보려면, 사전 오름차순 sorting 필수
• 시작용으로 iota 많이 사용 |
| std::transform | 변환 | std::transform(src.begin(), src.end(), dst.begin(), 함수);
//범위에 해당하는 부분에 함수처리해서 목표 위치에 출력
std::transform(
str.begin(),
str.end(),
str.begin(),
std::toupper //cctype 함수
);
//원본 덮어쓰기 가능
//문자열 대문자 변환
//문자열 소문자 변환에서는 std::tolower | • 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'; });
<numeric>
| 함수 | 설명 | ||
|---|---|---|---|
accumulate() |
init + 모든 원소 | std::accumulate(v.begin(), v.end(), init); | |
| std::accumulate(v.begin(), v.end(), 0); | |||
| std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>()) | • 원소 누적합을 위해서는 그냥 init에 0 넣기 | ||
| • 누적곱 때는 1 | |||
partial_sum() |
prefix sum(누적합 배열) 생성 | std::vector<int> v2 = { 1,2,3,4 }; | |
| std::vector<int> prefix(4); |
std::partial_sum(v2.begin(), v2.end(), prefix.begin());
//1 3 6 10 | • 구간합에 유용
• prefix[3] - prefix[1] == 7 |
| iota | 연속 값 채우기 | std::iota(v.begin(), v.end(), 5);
//5 6 7 8 9 | • permutation 시작용으로 매우 자주 사용 |
| gcd(a, b)
lcm(a, b) | 최대공약수
최소공배수 | std::gcd(a, b)
std::lcm(a, b) | • Greatest common divisor
• Least common multiple |
<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>
</aside>
<aside>
</aside>
<aside>
</aside>
<aside>
</aside>