Changyu Lee

코테 대비 C++/Python/SQL 주요 자료구조와 내장 함수들 정리

Published at
2025/09/23
Last edited time
2025/11/07 23:16
Created
2025/09/23 21:48
Section
Algorithm
Status
Done
Series
Tags
Basic
AI summary
Keywords
Coding Test
Language
KOR

C++

string

#include <iostream> #include <string> #include <algorithm> using namespace std; int main() { // ===== 1. 생성 & 초기화 ===== string s1 = "Hello"; string s2("World"); string s3(5, 'A'); // "AAAAA" string s4 = s1 + " " + s2; // "Hello World" cout << "[생성] " << s1 << " | " << s2 << " | " << s3 << " | " << s4 << "\n\n"; // ===== 2. 크기 & 접근 ===== string s = "hello"; cout << "[크기] size=" << s.size() << ", empty=" << boolalpha << s.empty() << "\n"; cout << "[접근] s[1]=" << s[1] << ", at(1)=" << s.at(1) << ", front=" << s.front() << ", back=" << s.back() << "\n\n"; // ===== 3. 수정 ===== s.push_back('!'); // hello! s.pop_back(); // hello s.insert(1, "123"); // h123ello s.erase(1, 3); // hello s.replace(0, 2, "yo"); // yollo cout << "[수정] " << s << "\n\n"; s.clear(); // "" cout << "[clear 후 empty] " << s.empty() << "\n\n"; // ===== 4. 부분 문자열 & 찾기 ===== string t = "abracadabra"; cout << "[substr] " << t.substr(0, 3) << "\n"; // "abr" cout << "[find] cad 위치: " << t.find("cad") << "\n"; // 4 cout << "[rfind] 마지막 a: " << t.rfind("a") << "\n"; // 10 cout << "[find_first_of] cd 중 첫 등장: " << t.find_first_of("cd") << "\n"; // 4 cout << "[find_last_of] 마지막 a 위치: " << t.find_last_of("a") << "\n\n"; // 10 // ===== 5. 비교 ===== string a = "apple", b = "banana"; cout << "[비교] (a==b)=" << (a==b) << ", (a<b)=" << (a<b) << ", compare=" << a.compare(b) << "\n\n"; // ===== 6. 변환 ===== string numStr = "12345"; int x = stoi(numStr); double y = stod("3.14"); string z = to_string(9876); cout << "[변환] stoi=" << x << ", stod=" << y << ", to_string=" << z << "\n\n"; // ===== 7. 순회 ===== string loopStr = "hello"; cout << "[순회 - 복사] "; for (auto c : loopStr) cout << c << " "; cout << "\n"; cout << "[순회 - 참조] "; for (auto& c : loopStr) c = toupper(c); cout << loopStr << "\n\n"; // ===== 8. 알고리즘 ===== string alg = " trim me "; reverse(alg.begin(), alg.end()); cout << "[reverse] " << alg << "\n"; sort(alg.begin(), alg.end()); cout << "[sort] " << alg << "\n"; // 공백 제거 (앞뒤만) string trimStr = " abc def "; trimStr.erase(0, trimStr.find_first_not_of(' ')); trimStr.erase(trimStr.find_last_not_of(' ')+1); cout << "[trim] '" << trimStr << "'\n"; return 0; }
C++
복사

vector

#include <vector> #include <algorithm> #include <iostream> using namespace std; int main() { vector<int> v; // 상태/용량 관련 cout << v.size() << "\n"; // 0 cout << boolalpha << v.empty() << "\n"; // true v.reserve(10); // capacity 미리 확보 cout << v.capacity() << "\n"; // 삽입/접근 v.push_back(10); v.emplace_back(20); // in-place 생성 v.insert(v.begin(), 5); // 임의 위치 삽입 if (!v.empty()) cout << v.front() << " " << v.back() << "\n"; // 5 20 cout << v[1] << " " << v.at(1) << "\n"; // 범위 체크(at) // 수정/삭제 v[0] = 7; v.erase(v.begin()); // 첫 원소 삭제 if (!v.empty()) v.pop_back(); // 중복 제거(정렬 + unique-erase 관용구) v = {3,1,2,2,3,3}; sort(v.begin(), v.end()); // 1 2 2 3 3 3 v.erase(unique(v.begin(), v.end()), v.end()); // 1 2 3 // 반복/순회 for (int x : v) cout << x << " "; // 기타 v.clear(); // 모두 삭제 v.shrink_to_fit(); // capacity 줄이기(힙 반환 시도) }
C++
복사

pair

#include <utility> #include <tuple> #include <iostream> using namespace std; int main() { pair<int,string> p = make_pair(1, "apple"); auto q = pair{2, string("banana")}; // C++17 class template argument deduction cout << p.first << " " << p.second << "\n"; // 비교(사전식) cout << boolalpha << (p < q) << "\n"; // tie / 구조적 바인딩 int id; string name; tie(id, name) = p; // tie auto [i, s] = q; // C++17 구조적 바인딩 }
C++
복사

map (정렬 맵, 중복 키 불가)

#include <map> #include <iostream> using namespace std; int main() { map<string,int> m; // 삽입/접근 m["apple"] = 3; // 없으면 생성 후 대입 m.insert({"banana", 5}); m.emplace("cherry", 7); m.try_emplace("date", 10); // key만 보고 생성(값 생성 비용↓) // 조회 if (!m.empty() && m.find("banana") != m.end()) cout << m.at("banana") << "\n"; // 범위 체크 .at cout << boolalpha << m.contains("apple") << "\n"; // C++20 // 정렬 특성 활용(lower_bound/upper_bound) auto it = m.lower_bound("b"); // key >= "b" 중 첫 원소 if (it != m.end()) cout << it->first << "\n"; // 순회(정렬된 키 순서) for (auto& [k, v] : m) cout << k << ":" << v << " "; // 삭제 m.erase("apple"); if (!m.empty()) m.erase(m.begin()); // 이터레이터로 삭제 m.clear(); }
C++
복사

set (정렬 집합, 중복 불가)

#include <set> #include <iostream> using namespace std; int main() { set<int> s; s.insert(10); s.emplace(5); s.insert(10); // 무시됨(중복 X) cout << s.size() << " " << boolalpha << s.empty() << "\n"; // 조회 if (s.find(5) != s.end()) cout << "5 있음\n"; cout << s.count(10) << "\n"; // 0 또는 1 // 범위 검색 auto it = s.lower_bound(6); // >= 6 if (it != s.end()) cout << *it << "\n"; // 순회 for (int x : s) cout << x << " "; // 삭제 s.erase(5); if (!s.empty()) s.erase(s.begin()); s.clear(); }
C++
복사

queue (FIFO)

#include <queue> #include <iostream> using namespace std; int main() { queue<int> q; cout << boolalpha << q.empty() << "\n"; // true q.push(1); q.emplace(2); q.push(3); // 사용 전 항상 empty() 체크 while (!q.empty()) { cout << q.front() << " "; // 맨 앞 q.pop(); // 제거 } // back(), size(), swap() q.push(10); q.push(20); if (!q.empty()) cout << q.back() << "\n"; // 맨 뒤 cout << q.size() << "\n"; }
C++
복사

deque (양쪽 입출, 임의 접근)

#include <deque> #include <iostream> using namespace std; int main() { deque<int> dq; cout << boolalpha << dq.empty() << "\n"; // true dq.push_back(10); dq.push_front(20); dq.emplace_back(30); if (!dq.empty()) { cout << dq.front() << " " << dq.back() << "\n"; // 20 30 cout << dq[1] << "\n"; // 임의 접근 cout << dq.at(1) << "\n"; // 범위 체크 } dq.pop_front(); dq.pop_back(); // insert/erase (중간 삽입/삭제도 vector보다 유리) dq.insert(dq.begin(), 99); if (!dq.empty()) dq.erase(dq.begin()); dq.clear(); }
C++
복사

priority_queue (기본: 최대 힙)

#include <queue> #include <vector> #include <iostream> using namespace std; int main() { // 최대 힙 priority_queue<int> pq; cout << boolalpha << pq.empty() << "\n"; // true pq.push(3); pq.emplace(10); pq.push(5); // 사용 전 empty() 체크 습관화 while (!pq.empty()) { cout << pq.top() << " "; // 가장 큰 값 pq.pop(); } // 최소 힙 priority_queue<int, vector<int>, greater<int>> minpq; for (int x : {7,1,4}) minpq.push(x); if (!minpq.empty()) cout << "\nmin: " << minpq.top() << "\n"; // 사용자 정의(예: pair에서 score 큰 순) using P = pair<int,int>; // {score, id} struct Cmp { bool operator()(const P& a, const P& b) const { return a.first < b.first; // 큰 score가 먼저 나오도록(최대 힙 성향) } }; priority_queue<P, vector<P>, Cmp> rpq; rpq.emplace(95, 2); rpq.emplace(87, 5); rpq.emplace(99, 1); while (!rpq.empty()) { auto [score, id] = rpq.top(); cout << score << ":" << id << " "; rpq.pop(); } }
C++
복사

sort 계열 알고리즘(algorithm)

#include <vector> #include <algorithm> #include <iostream> using namespace std; struct Node { int a, b; }; int main() { vector<int> v = {5,1,4,2,3}; // sort: 기본 오름차순 sort(v.begin(), v.end()); // 1 2 3 4 5 // 내림차순 sort(v.begin(), v.end(), greater<int>()); // 5 4 3 2 1 // 사용자 정의 비교 vector<Node> arr = {{1,3},{1,2},{2,1}}; sort(arr.begin(), arr.end(), [](const Node& x, const Node& y){ if (x.a != y.a) return x.a < y.a; // a 오름차순 return x.b > y.b; // a 동률이면 b 내림차순 }); // stable_sort: 같은 값의 상대적 순서 보장 stable_sort(v.begin(), v.end()); // partial_sort: 상위 k개만 정렬 int k = 3; partial_sort(v.begin(), v.begin()+k, v.end()); // 앞 k개가 정렬된 상태 // nth_element: n번째 원소가 올 자리에 오도록(partition) nth_element(v.begin(), v.begin()+k, v.end()); // v[k]는 정렬 기준상 정확 위치 // 이진 탐색 계열(정렬 필요) sort(v.begin(), v.end()); bool has3 = binary_search(v.begin(), v.end(), 3); auto itL = lower_bound(v.begin(), v.end(), 3); // 첫 >= 3 auto itU = upper_bound(v.begin(), v.end(), 3); // 첫 > 3 cout << boolalpha << has3 << " " << (itL - v.begin()) << " " << (itU - v.begin()) << "\n"; // reverse/rotate reverse(v.begin(), v.end()); rotate(v.begin(), v.begin()+1, v.end()); // 좌회전 1칸 }
C++
복사
보너스: 컨테이너 선택 간단 가이드
인덱스 접근·끝 삽입/삭제가 많다: vector
양끝 삽입/삭제가 많다: deque
키-값 보관, 키 정렬 필요: map (정렬)
원소 집합, 정렬·범위쿼리: set / 중복 허용 multiset
단순 FIFO: queue
최댓값/최솟값을 자주 꺼낸다: priority_queue
정렬/이진탐색이 필요하면 먼저 sort, 그 다음 binary_search/lower_bound/upper_bound
추가적으로
map<int, priority_queue<int, vector<int>, greater<int>>> under5; // ID 기반 점수 오름차순 map<int, priority_queue<int, vector<int>>> top5; // ID 기반 점수 내림차순 // vector에서 중복 제거 // 1) 정렬 sort(v.begin(), v.end()); // 1 2 2 3 3 3 4 // 2) unique → 연속된 중복 원소 제거 (뒤로 밀림) auto it = unique(v.begin(), v.end()); // [1,2,3,4, ?, ?, ?] // 3) erase → 실제 vector 크기 줄이기 v.erase(it, v.end()); // [1,2,3,4] // 기존 인덱스를 가지고 있으면서 정렬 vector<int> nums = {50, 20, 50, 10}; vector<pair<int,int>> vp; for (int i = 0; i < (int)nums.size(); i++) { vp.push_back({nums[i], i}); } sort(vp.begin(), vp.end()); // (값, 인덱스) 기준 정렬됨 오름차순 sort(vp.begin(), vp.end(), greater<pair<int,int>>()); // 내림차순 // 배열에서 숫자가 나온 만큼을 frequency로 정리 map<int,int> freq; // key: 값, value: 빈도수 for (int x : nums) { freq[x]++; }
C++
복사

Python

1. heapq 사용법 (최소 힙 기반)

import heapq # 기본 힙(최소 힙) h = [] heapq.heappush(h, 3) heapq.heappush(h, 1) heapq.heappush(h, 5) print(h[0]) # 최소값 조회 print(heapq.heappop(h)) # 최소값 꺼내기 # 리스트를 힙으로 변환 arr = [7, 2, 9, 1] heapq.heapify(arr) # 최대 힙(음수 변환) maxh = [] for x in [3,1,5]: heapq.heappush(maxh, -x) print(-heapq.heappop(maxh)) # 최대값 # 상위/하위 k개 nums = [9,1,5,3,7] print(heapq.nsmallest(3, nums)) # [1,3,5] print(heapq.nlargest(2, nums)) # [9,7]
Python
복사

2. deque 사용법 (양쪽 O(1) 삽입/삭제)

from collections import deque dq = deque([1,2,3]) # 양쪽 삽입/삭제 dq.append(4) # 오른쪽에 추가 dq.appendleft(0) # 왼쪽에 추가 dq.pop() # 오른쪽 제거 dq.popleft() # 왼쪽 제거 # 기타 dq.rotate(1) # 오른쪽으로 회전 dq.rotate(-2) # 왼쪽으로 회전 print(len(dq), dq[0], dq[-1]) for i in range(m): for k in range(n): if visited[i][k] or grid[i][k] == "0": continue queue = deque([(i, k)]) visited[i][k] = True num += 1 while queue: x, y = queue.popleft() for dx, dy in dirs: nx, ny = x + dx, y + dy if 0 <= nx < m and 0 <= ny < n: if not visited[nx][ny] and grid[nx][ny] == "1": visited[nx][ny] = True queue.append((nx, ny))
Python
복사

3. 문자열(str) 관련 패턴

s = " Hello, Python 3.10! " # 길이/접근 len(s), s[0], s[-1], s[2:7], s[::-1] # 문자열 뒤집기 # 공백 제거 s.strip(), s.lstrip(), s.rstrip() # 분할/결합 "John,Doe".split(",") " ".join(["a","b","c"]) # 찾기/검사 s.find("Python"), s.count("o") s.startswith("He"), s.endswith("!") # 치환 "2025-09-23".replace("-", "/") # 대소문자 "heLLo".lower(), "heLLo".upper(), "abc".title() # 포맷팅 f"Alice got {97.5:.1f}" "{:,.0f}".format(1234567) # 판별 "123".isdigit(), "abc".isalpha(), "a1".isalnum()
Python
복사

SQL

SQL 기본 – CRUD

SQL은 보통 데이터를 다루는 네 가지 기본 동작(CRUD)을 기반으로 합니다.
작업
명령어
설명
C(Create)
INSERT
데이터 추가
R(Read)
SELECT
데이터 조회
U(Update)
UPDATE
데이터 수정
D(Delete)
DELETE
데이터 삭제
(1) CREATE – 데이터 삽입
CREATE TABLE Employee ( empId INT PRIMARY KEY, -- PK는 자동으로 NOT NULL name VARCHAR(50) NOT NULL, -- 이름은 반드시 값이 있어야 함 salary INT NULL -- 급여는 없어도 됨 (기본은 NULL 허용) ); CREATE TABLE Bonus ( empId INT, -- Employee.empId를 참조 bonus INT default 0, -- 보너스 금액 디폴트 0 FOREIGN KEY (empId) REFERENCES Employee(empId) ); -- students 테이블에 한 줄 삽입 INSERT INTO students (id, name, age, major) VALUES (1, 'Alice', 20, 'Computer Science'); -- 여러 줄 삽입 INSERT INTO students (id, name, age, major) VALUES (2, 'Bob', 22, 'Physics'), (3, 'Charlie', 21, 'Mathematics'); -- 일부 삽입 -- name만 넣고, 나머지는 NULL INSERT INTO Employee (name) VALUES ('Charlie');
SQL
복사
(2) READ – 데이터 조회 (SELECT)
-- 모든 열 조회 SELECT * FROM students; -- 특정 열만 조회 SELECT name, age FROM students; -- 별칭 사용 SELECT name AS student_name, age AS student_age FROM students;
SQL
복사
(3) UPDATE – 데이터 수정
-- 조건에 맞는 데이터 수정 UPDATE students SET age = 23 WHERE id = 2; -- UPDATE Salary as s SET s.sex = CASE s.sex WHEN 'f' THEN 'm' WHEN 'm' THEN 'f' ELSE s.sex END;
SQL
복사
(4) DELETE – 데이터 삭제
-- 조건에 맞는 데이터 삭제 DELETE FROM students WHERE id = 3; -- 전체 삭제 (주의!) DELETE FROM students;
SQL
복사

SELECT 문 – 조건/정렬/제한

-- 조건 필터링 SELECT * FROM students WHERE age >= 21; -- 정렬 SELECT * FROM students ORDER BY age DESC; -- 제한 (MySQL, PostgreSQL) SELECT * FROM students ORDER BY age DESC LIMIT 2;
SQL
복사

WHERE 절 – 다양한 조건

-- 비교 연산 SELECT * FROM students WHERE age = 20; SELECT * FROM students WHERE age BETWEEN 20 AND 22; -- 문자열 패턴 SELECT * FROM students WHERE name LIKE 'A%'; -- A로 시작 SELECT * FROM students WHERE name LIKE '%e'; -- e로 끝남 -- 집합 SELECT * FROM students WHERE major IN ('Physics', 'Mathematics'); -- 논리 연산 SELECT * FROM students WHERE age > 20 AND major = 'Physics';
SQL
복사

GROUP BY – 집계 함수와 함께

GROUP BY는 데이터를 그룹화하고 집계 함수를 적용할 때 사용합니다.
주요 집계 함수:
COUNT(*) : 개수
SUM(col) : 합
AVG(col) : 평균
MIN(col) / MAX(col) : 최소, 최대
-- 전공별 학생 수 SELECT major, COUNT(*) AS num_students FROM students GROUP BY major; -- 전공별 평균 나이 SELECT major, AVG(age) AS avg_age FROM students GROUP BY major;
SQL
복사

HAVING – 그룹 조건

WHERE는 그룹핑 이전 조건,
HAVING은 그룹핑 이후 조건에 사용합니다.
-- 전공별 학생 수가 1명 이상인 전공만 SELECT major, COUNT(*) AS num_students FROM students GROUP BY major HAVING COUNT(*) >= 2; -- 전공별 평균 나이가 21 이상인 전공만 SELECT major, AVG(age) AS avg_age FROM students GROUP BY major HAVING AVG(age) >= 21;
SQL
복사
예제 (종합)
-- 21세 이상인 학생들 중 전공별 평균 나이를 구하고, -- 그 평균이 22 이상인 전공만, 평균 나이 내림차순 정렬 SELECT major, AVG(age) AS avg_age FROM students WHERE age >= 21 GROUP BY major HAVING AVG(age) >= 22 ORDER BY avg_age DESC;
SQL
복사
정리
CRUD = Insert / Select / Update / Delete
WHERE: 그룹화 전 조건
GROUP BY: 그룹 단위 집계
HAVING: 그룹화 후 조건

JOIN

테이블 A와 B가 있을 때, 공통된 **키(column)**를 기준으로 데이터를 합치는 것
보통 PRIMARY KEYFOREIGN KEY 관계에서 자주 사용됨
예시 테이블:
students +----+--------+------+ | id | name | age | +----+--------+------+ | 1 | Alice | 20 | | 2 | Bob | 22 | | 3 | Charlie| 21 | +----+--------+------+ enrollments +----+-----------+----------+ | id | student_id| course | +----+-----------+----------+ | 1 | 1 | Math | | 2 | 1 | Physics | | 3 | 2 | Chemistry| +----+-----------+----------+
Plain Text
복사

1. INNER JOIN (교집합)

양쪽 테이블에서 조건에 일치하는 데이터만 가져옴
SELECT s.name, e.course FROM students s INNER JOIN enrollments e ON s.id = e.student_id;
SQL
복사
결과:
Alice Math Alice Physics Bob Chemistry
Plain Text
복사

2. LEFT JOIN (왼쪽 테이블 기준)

왼쪽 테이블(students)의 모든 행을 가져오고,
오른쪽(enrollments)에서 일치하는 값이 있으면 붙이고, 없으면 NULL
SELECT s.name, e.course FROM students s LEFT JOIN enrollments e ON s.id = e.student_id;
SQL
복사
결과:
Alice Math Alice Physics Bob Chemistry Charlie NULL
Plain Text
복사

3. RIGHT JOIN (오른쪽 테이블 기준)

오른쪽 테이블(enrollments)의 모든 행을 가져오고,
왼쪽(students)에서 일치하는 값이 없으면 NULL
SELECT s.name, e.course FROM students s RIGHT JOIN enrollments e ON s.id = e.student_id;
SQL
복사
결과:
Alice Math Alice Physics Bob Chemistry
Plain Text
복사
(만약 enrollments에 학생 없는 데이터가 있으면 name = NULL)

4. FULL OUTER JOIN (합집합)

두 테이블을 모두 포함
어느 한쪽에만 있어도 결과에 나타남
MySQL은 직접 지원하지 않고 UNION으로 흉내냄
SELECT s.name, e.course FROM students s FULL OUTER JOIN enrollments e ON s.id = e.student_id;
SQL
복사

5. CROSS JOIN (카르테시안 곱)

두 테이블의 모든 조합을 생성 (조건 X)
SELECT s.name, e.course FROM students s CROSS JOIN enrollments e;
SQL
복사
결과 = 학생 수 × 수강행 수 (매우 커질 수 있음)

6. SELF JOIN (자기 자신과 JOIN)

같은 테이블을 두 번 불러와서 JOIN
-- 같은 나이인 학생끼리 묶기 SELECT a.name AS student1, b.name AS student2 FROM students a JOIN students b ON a.age = b.age AND a.id < b.id;
SQL
복사

7. JOIN + GROUP BY (응용)

JOIN은 보통 집계와 함께 많이 씁니다.
-- 각 학생이 수강하는 과목 수 SELECT s.name, COUNT(e.course) AS num_courses FROM students s LEFT JOIN enrollments e ON s.id = e.student_id GROUP BY s.name;
SQL
복사
정리
INNER JOIN: 공통된 행만
LEFT JOIN: 왼쪽 전부 + 매칭
RIGHT JOIN: 오른쪽 전부 + 매칭
FULL OUTER JOIN: 둘 다 전부
CROSS JOIN: 모든 조합
SELF JOIN: 자기 자신과 JOIN
Additionally
ID를 할 때 Distinct를 써야함에 주의