0. 알아두면 좋은
#include <bits/stdc++.h>
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int fn(int* p){
*p = 33;
}
int a = 1;
fn(&a);
void fn(vector<int> &v){
v[1] = 333;
}
vector<int> g = {2, 3, 4, 5};
fn(g);
1. Vector 벡터
1. vector STL
#inclue <vector>
using namespace std;
vector<int> v;
vector<int> v2(4);
vector<int> v3(5, 2);
vector<int> v4(v2);
v.assign(5, 2);
v.at(2);
v[2];
v.front();
v.back();
v.clear();
v.push_back(3);
v.pop_back();
v.begin();
v.end();
v.reserve(n);
v.resize(n);
v.resize(n, 3);
v.insert(v.begin() + 2, 3);
v.insert(v.begin() + 2, 3, 4);
2. 이차원 벡터 입력
vector<vector<int>> graph;
for (int i = 0; i <= n; i++) {
vector<int> v;
graph.push_back(v);
}
for (int i = 0; i < m; i++) {
int a, b;
scanf("%d %d", &a, &b);
graph[a].push_back(b);
}
vector<vector<int>> vv(3, vector<int>(5, 3));
3. vector sort() (벨로그)
bool comp(const int o1, const int o2){
return true;
return false;
}
bool comp(const int o1, const int o2){
return o1 <= o2;
}
bool comp(const int o1, const int o2){
return o1 > o2;
}
bool comp(const int o1, const int o2){
if(condition1[o1] == condition1[o2]){
if(condition2[o1] < condition2[o2]){
return true;
}
else{
return false;
}
}
else if(condition1[o1] > conditoin1[o2]){
return true;
}
else{
return false;
}
}
sort(v.begin(), v.end());
sort(v.begin(), v.end(), less<int>());
sort(v.begin(), v.end(), greater<int>());
sort(v.begin(), v.end(), comp);
이차원 벡터 시계방향 회전
vector<vector<int>> clockwiseRotate(vector<vector<int>> v, int count){
int size = v.size();
vector<vector<int>> result = v;
for(int t = 0; t < count; t++){
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
result[j][size - i - 1] = v[i][j];
}
}
v = result;
}
return result;
}
이차원 벡터 반시계방향 회전
vector<vector<int>> counterClockwiseRotate(vector<vector<int>> v, int count){
int size = v.size();
vector<vector<int>> result = v;
for(int t = 0; t < count; t++){
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
result[size - j -1][i] = v[i][j];
}
}
v = result;
}
return result;
}
2. Stack 스택 (벨로그)
3. queue 큐 (벨로그)
4. priority_queue 우선순위 큐 (벨로그)
priority_queue<int> pq;
priority_queue<int, vector<int>, compare> pq;
priority_queue<int, vector<int>, less<int>> pq;
priority_queue<int, vector<int>, greater<int>> pq;
struct compare{
bool operator()(int a, int b){
return a < b;
}
};
struct Data{
int idx;
int value;
};
struct Comp{
bool operator()(const Data& a, const Data& b){
return a.value > b.value;
}
};
priority_queue<int, vector<int>, Comp> pq;
pq.push({idx, value});
pq.top();
pq.pop();
while(!pq.empty()){
pq.pop();
}
priority_queue<int> pq;
priority_queue<int, vector<int>, less<int>> maxHeap;
priority_queue<int, vector<int>, greater<int>> minHeap;
6. Binary Search 이분 탐색
int left = 0;
int right = n;
while(left <= right){
int mid = (left + right) / 2;
if(data[mid] == target){
exist = true;
break;
}
else if(data[mid] > target){
right = mid - 1;
}
else{
left = mid + 1;
}
}
7. Two Pointer 투 포인터
sort(AB.begin(), AB.end());
sort(CD.begin(), CD.end(), greater<int>);
long long int result = 0;
int ptab = 0, ptcd = 0;
while (ptab < AB.size() && ptcd < CD.size()) {
int currentAB = AB[ptab];
int target = -currentAB;
if (CD[ptcd] == target) {
int ab = 0, cd = 0;
while(AB[ptab] == currentAB && ptab < AB.size()){
ab++;
ptab++;
}
while(CD[ptcd] == target && ptcd < CD.size()){
cd++;
ptcd++;
}
result += (long long int) ab * cd;
}
else if (CD[ptcd] > target) {
ptcd++;
}
else {
ptab++;
}
}
8. multiset 멀티셋 중복 Key 값 (벨로그)
multiset<int> ms;
multiset<int, less<int>> ms;
multiset<int, greater<int>> ms;
ms.insert(50);
ms.insert(50);
ms.insert(10);
ms.insert(80);
ms.insert(80);
ms.erase(ms.begin());
ms.erase(--ms.end());
multiset<int>::iterator it;
for(it = ms.begin(); it != ms.end(); it++){
cout << *it;
}
9. unordered_map 해쉬테이블
unordered_map<string, int> u;
u["A"] = 1;
u["B"] = 22;
for(auto elem : u){
cout<<"key : "<<elem.first<<" value : "<<elem.second<<endl;
}
unordered_map<string, vector<int>> u;
vector<int> v;
string key = "abc";
u[key] = v;
u[key].push_back(2);
u[key].push_back(66);
for(int i = 0; i < u[key].size(); i++){
cout << u[key][i] << " ";
}
10. String
string s;
cin >> s;
while(getline(cin, s)){
cout << s << endl;
}
char str[25];
scanf("%s, str);
strlen(str);
char cstr[1010] = "";
scanf("%s", cstr);
string st(cstr);
cout << st;
int num = 10;
cout << to_string(number);
stoi = string to int
stof = string to float
stol = string to long
stoll = string to long long
stod = string to double
for(auto i : s){
cout << i << endl
}
string base = "this is a test string.";
string replace = "example 1";
base.replace(9, 5, replace);
reverse(s.begin(), s.end());
string s = "helloll"
cout << s.find("ll") << endl;
cout << s.find("ll", 3) << endl;
cout << s.substr(0, 4) << endl;
cout << s.substr(5) << endl;
cout << s.replace(3, 2, "rr") << endl;
cout << s << endl;
for(int i = 0; i < s.length(); i++){
s[i] = toupper(s[i]);
}
cout << s << endl;
for(int i = 0; i < s.length(); i++){
s[i] = tolower(s[i]);
}
cout << s << endl;
string str = " jo hye jeong ";
str.erase(remove(str.begin(), str.end(), ' '), str.end());
cout << str << endl;
vector<string> split(string str, char delimiter) {
vector<string> answer;
int prev = 0, current = str.find(delimiter);
while (current != -1) {
string tmp = str.substr(prev, current - prev);
answer.push_back(tmp);
prev = current + 1;
current = str.find(delimiter, prev);
}
answer.push_back(str.substr(prev, current - prev));
return answer;
}
int main(){
vector<string> subS = split(s, ' ');
}
9. 최대공약수 (유클리드호제법) (벨로그)
int gcd(int a, int b){
return b ? gcd(b, a % b) : a;
}
int lcm(int a, int b) {
return (a * b) / gcd(a, b);
}
10. 에라토스테네스의 체
bool isPrime[MAX];
vector<int> prime;
for (int i = 0; i < MAX; i++) {
isPrime[i] = true;
}
for (int i = 2; i < MAX; i++) {
if (isPrime[i]) {
prime.push_back(i);
for(int j = 2 * i; j < MAX; j += i) {
isPrime[j] = false;
}
}
}
11. 트리 순회
12. Union Find 서로소 집합
vector<int> parent;
void init() {
for (int i = 0; i <= n; i++) {
parent.push_back(i);
}
}
int find(int a) {
if (parent[a] != a)
parent[a] = find(parent[a]);
return parent[a];
}
void unionF(int a, int b) {
int pa = find(a);
int pb = find(b);
parent[pb] = pa;
}
if(find(a) == find(b)){
}
Topological Sort 위상 정렬 (벨로그)
queue<int> q;
for (int i = 1; i <= n; i++) {
if (student[i] == 0) {
q.push(i);
}
}
while (!q.empty()) {
int front = q.front();
q.pop();
printf("%d ", front);
for (int i = 0; i < graph[front].size(); i++) {
if (--student[graph[front][i]] == 0) {
q.push(graph[front][i]);
}
}
}
Kruskal's Algorithm 크루스칼 알고리즘 - 최소 스패닝 트리(MST) (벨로그)
struct Edge{
int nodeA;
int nodeB;
int weight;
};
struct Comp{
bool operator()(const Edge& A, const Edge& B){
return A.weight > B.weight;
}
};
vector<int> parent;
int find(int node){
if(node == parent[node]) return node;
else return find(parent[node]);
}
void unionF(int a, int b){
int pA = find(a);
int pB = find(b);
parent[pA] = pB;
}
priority_queue<Edge, vector<Edge>, Comp> edges;
int edge = 0;
int result = 0;
for(int i = 0; i <= v; i++){
parent.push_back(i);
}
for(int i = 0; i < e; i++){
int a, b, w;
scanf("%d %d %d", &a, &b, &w);
edges.push({a, b, w});
}
while(edge < v - 1 || !edges.empty()){
Edge minE = edges.top();
edges.pop();
if(find(minE.nodeA) != find(minE.nodeB)){
unionF(minE.nodeA, minE.nodeB);
result += minE.weight;
edge++;
}
}
Dijstra Algorithm (다익스트라 알고리즘) (벨로그)
특정한 하나의 정점에서 모든 정점으로의 최소 경로 (단, 음의 간선은 없다)
struct Edge{
int id;
int cost;
};
struct Comp{
bool operator()(const Edge& a, const Edge& b){
return a.cost > b.cost;
}
};
vector<vector<Edge>> adjList;
vector<int> dist;
void dijkstra(int start){
priority_queue<Edge, vector<Edge>, Comp> pq;
dist[start] = 0;
pq.push({start, dist[start]});
while(!pq.empty()){
Edge now = pq.top();
pq.pop();
if(dist[now.id] < now.cost) continue;
int size = adjList[now.id].size();
for(int i = 0; i < size; i++){
Edge next = adjList[now.id][i];
if(dist[next.id] > now.cost + next.cost){
dist[next.id] = now.cost + next.cost;
pq.push({next.id, dist[next.id]});
}
}
}
}
플로이드 워셜 알고리즘 (최단 경로)
모든 정점에서 모든 정점으로의 최단 경로
const int INF = 1E9;
int main(){
int n, m;
scanf("%d %d", &n, &m);
vector<vector<int>> graph(n+1);
for(int i = 0; i <= n; i++){
for(int j = 0; j <= n; j++){
if(i == j) graph[i].push_back(0);
else graph[i].push_back(INF);
}
}
for(int j = 0; j < m; j++){
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
graph[a][b] = c;
}
for(int k = 1; k <= n; k++){
for(int a = 1; a <= n; a++){
for(int b = 1; b <= n; b++){
graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]);
}
}
}
return 0;
}
DFS
void dfs(vector<vector<int>> &graph, int node, vector<bool> &visite
visited[node] = true;
printf("%d\n", node);
for(int i = 0; i < graph[node].size(); i++){
int idx = graph[node][i];
if(!visited[idx]){
dfs(graph, idx, visited);
}
}
}
int main(){
vector<vector<int>> graph = {
{},
{2, 3, 7},
{1, 7},
{1, 4, 5},
{3, 5},
{3, 4},
{7},
{2, 6, 8},
{1, 7}
};
vector<bool> visited(graph.size(), false);
dfs(graph, 1, visited);
return 0;
}
BFS
void bfs(vector<vector<int>> &graph, int node, vector<bool> &visited){
visited[node] = true;
queue<int> q;
q.push(node);
while(!q.empty()){
int top = q.front();
q.pop();
printf("%d\n", top);
for(int i = 0; i < graph[top].size(); i++){
int idx = graph[top][i];
if(!visited[idx]){
q.push(idx);
visited[idx] = true;
}
}
}
}
int main(){
vector<vector<int>> graph = {
{},
{2, 3, 8},
{1, 7},
{1, 4, 5},
{3, 5},
{3, 4},
{7},
{2, 6, 8},
{1, 7}
};
vector<bool> visited(graph.size(), false);
bfs(graph, 1, visited);
return 0;
}
상하좌우 움직이기 (완전 탐색 & DFS)
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
void ice(vector<vector<int>> &graph, int y, int x){
if(graph[y][x] == 1) return;
graph[y][x] = 1;
for(int i = 0; i < 4; i++){
ice(graph, y + dy[i], x + dx[i]);
}
}
이차원 벡터 초기화 (상하좌우 blocking)
int n, m;
scanf("%d %d", &n, &m);
vector<vector<int>> data(n+2);
for(int i = 0; i < n+2; i++){
data[i].resize(m+2, 1);
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
int x;
scanf("%1d", &x);
data[i][j] = x;
}
}
이차원 벡터 BFS (pair / make_pair)
void mapBFS(vector<vector<int>> &graph, vector<vector<bool>> &visited, int y, int x){
visited[y][x] = true;
queue<pair<int, int>> q;
q.push(make_pair(y, x));
while(!q.empty()){
pair<int, int> front = q.front();
q.pop();
int currY = front.first;
int currX = front.second;
for(int i = 0; i < 4; i++){
int nextY = currY + dy[i];
int nextX = currX + dx[i];
if(!visited[nextY][nextX]){
q.push(make_pair(nextY, nextX));
graph[nextY][nextX] = graph[currY][currX] + 1;
visited[nextY][nextX] = true;
}
}
}
}
int main(){
int n, m;
scanf("%d %d", &n, &m);
vector<vector<int>> data(n+2);
vector<vector<bool>> visited(n+2);
for(int i = 0; i < n+2; i++){
data[i].resize(m+2, 1);
visited[i].resize(m+2, true);
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
int x;
scanf("%1d", &x);
data[i][j] = x;
visited[i][j] = false;
}
}
mapBFS(data, visited, 1, 1);
printf("%d", data[n][m]);
return 0;
}
약수의 개수 구하기
int number = 12, divCount = 0;
for(int i = 1; i * i <= number; i++){
if(number % i == 0){
divCount++;
if(i * i < number){
divCount++;
}
}
}
정규 표현식
✔ 헤더
#include <regex>
✔ 정규식 생성
regex re("~~~~");
✔ Syntax (문법)
^x : '^'는 문자열 시작을 의미 (x로 시작한다.)
x$ : '$'는 문자열 종료를 의미 (x로 끝난다.)
.x : '.'은 개행문자(\n)를 제외한 모든 문자를 의미
x+ : '+'는 1회 이상 반복을 의미 ({1, }와 같음)
x* : '*'은 0회 이상 반복을 의미({0, }와 같음)
x? : '?'는 0 or 1개의 문자 매칭을 의미 ({0, 1})
x|y : '|' 는 or을 의미 (x또는 y)
(x) : '()'는 그룹을 표현 ex) (abc){3} ⇒ abcabcabc 검출
x{n} : '{}'는 반복을 의미 x가 n번 반복된다.
x{n, } : x가 n번 이상 반복된다.
x{n, m} : x가 n번 ~ m번 사이 반복된다.
[xy] : '[]'는 x or y를 찾는다는 의미. ([a-z0-9] ⇒ 소문자 or 숫자)
[^xy] : '[^]'은 not을 의미. (xy 제외하고 찾는다.)
\\d : 숫자 (digit)
\\D : 숫자 제외 (not digit)
\\s : 공백 (space)
\\S : 공백 제외 (not space)
\\t : tab
\\w : 알파벳 (대, 소문자), 숫자 [A-Za-z0-9]
\\W : \w 제외한 특수문자
✔ Code
for(int i = 0; i < queries.size(); i++){
string reg = "";
int qmCount = 0;
for(int j = 0; j < queries[i].length(); j++){
if(queries[i][j] == '?'){
qmCount ++;
}
else{
if(qmCount > 0){
reg += "\\w{" + to_string(qmCount) + "}";
qmCount = 0;
}
reg += queries[i][j];
}
}
if(qmCount > 0){
reg += "\\w{" + to_string(qmCount) + "}";
}
regex re(reg);
int result = 0;
for(int j = 0; j < words.size(); j++){
if(regex_match(words[j], re)){
result ++;
}
}
answer.push_back(result);
}