Every programming is about treating data. Therefore, understanding of data type is crucial for all the developers.
v, r = divmod(7, 3)
1e9
may replace float('inf')
if upper limit is less than 1e9.0.1 * 3 == 0.3 # _False_
(1, 3)
rather than 1/3
or 0.3333
for i in range(10000):
s = s + str(i) # 5.96 us
s = s.join([str(i) for i in range(10000)]) # 5.01 us
split
, replace
, and find
chr(65) # ‘A’
ord(‘A’) # 65
[a, b, c]
다량의 입력은 list comprehension 이 더 좋음 ex) 10 명의 값 정수로?
v = [int(input()) for i in range(10)]
1차 배열 초기화 할땐 n 만큼 곱하는게 빠름
# 1D array init
a = [0] * N
# 2D array init
b = [[0] * M for _ in range(N)]
# Wrong use of comprehension (2d init)
c = [[0] * M] * N
print(c) # [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
c[1][1] = 7 # [[0, 7, 0], [0, 7, 0], [0, 7, 0], [0, 7, 0]]
print(c)
(a, b, c)
a, b, c = 0, 0, 0 # init
a, b = map(int, sys.stdin.readline().split()) # multiple input in one line
a, b = b, a # swap
(Cost, Node_A)
{a : 1, b : 2, c : 3 }
d = {1:2, 3:4, 'asd':5}
d.keys()
d.values()
for k, v for d:
print(k, end=' ')
print(v)
import collections
collections.Counter('aasddd') # Counter({'a': 2, 's': 1, 'd': 3})
for key in dict_list: pass
기본적으로 키값 유무 확인dict_test.get(y, “false”)
# 있으면 y 주고 없으면 false 리턴{a, b, c}
def isCheck(list):
return len(list) == len(set(list))
a = [1, 2, 2, 4, 4, 6]
rm_set = {2, 6}
result = [i for i in a if i not in rm_set]
print(result) # [1, 4, 4]
var.add(#)
var.update([#, #])
var.remove(#)
a = input()
a = input().split()
a, b, c = map(int, input().split())
if data > 10,000,000 | searching range > 100,000,000,000 and use binary search. |
sys.stdin.readline().split().rstrip()
from sys import stdin
a = stdin.readline().split().rstrip() # rstrip strips \n white space triggered by 'enter' key
for i in range(N):
for idx, v in enumerate(list(map(int, list(input())))):
A[i+1][idx+1] = v
std lib #include <bits/stdc++.h>
Cin 보다 scanf가 더 빠름 !!
// 1 2
int N, M;
scanf(“%d %d”, &N, &M); // way 1
cin >> N >> M; // way 2
// 1 2 3
int card[100];
for (int i=0; i<N; i++):
scanf(“%d”, card + i);
/*
123
345
*/
cin >> n >> m;
for (int i=0; i<N; i++) {
for (int j=0; j<M; j++) {
scanf("%1d", &graph[i][j]);
}
}
import java.util.*;
list lib import
1 2
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
Scanner sc = new Scanner(System.in);
String str = sc.next();
print('\n'.join(str(i) for i in map(int, input().split()) if i % 2 == 0))
a, b, c = "a", 4, 5.0123
print("{}.{:02d}.{:02d}".format(a,b,c))
ans = 8
print(f"answer is {ans}.")
print(eval("(1+2)*3")) # 9
print((lambda a, b: a + b)(3, 7)) # 10
# 2번째 원소 키값으로 정렬, 나머지 키들의 순서는 정렬안하고 유지함.
a = sorted(a, key = lambda x: x[1])
list1 = [1, 2, 3]
list2 = [3, 4, 5]
result = map(lambda a, b: a + b, list1, list2)
print(list(result)) # [4, 6, 8]
map(func, iterable)
# apply function to all iterable elements and return map obj.
arr = [1, 2, 3]
result = list(map(lambda i: i ** 2 , arr)) # [1, 4, 9]
filter(func, iterable)
# apply function to all iterable elements and return only if true (function’s return value must be true/false)
``` python
arr = [-2, -3, 5, 6]def ft(arr): result = [] for e in arr: if e > 0: result.append(e) return result
def positive(x): return x > 0
list(filter(positive, arr)) list(filter(lambda x: x > 0, arr)) # filter + lambda
## Using zip
- Grouping column in 2d array
``` python
list(zip([1, 2, 3], [4, 5, 6])) # [(1, 4), (2, 5), (3, 6)]
list(zip([1, 2, 3], [4, 5, 6], [7, 8, 9])) # [(1, 4, 7), (2, 5, 8), (3, 6, 9)
list(zip("abc", "def")) # [('a', 'd'), ('b', 'e'), ('c', 'f')]
함수 정의시 위에 주석으로 함수 역할과 인자 설명 써두면 좋음
# moneySum: 돈의 합 출력 # N: 사람수, moneyArr: 사람의 돈 def moneySum(N, moneyArr): ret = 0 return ret
def op(a,b):
qwe = a + b
asd = a - b
zxc = a // b
returm qwe, asd, zxc
a, b, c = op(1, 2)
컨테이너의 역할
컨테이너의 분할
A = [[0 for i in range(2)] for j in range(100)] # 1번째 값은 순서, 2번째값은 A[i][0], A[i][1]
위처럼 한번에 하는거보다 A[1000], V[1000] 같이 나눠서 하는게 가독성을 높일 수 있음. 그때그때 편한대로 사용.
2차원 배열 마지막 row 중 최대: map(arr[-1])
논리/비트 연산자 활용
a, b = 10, 20
if a > b:
if a % 10 == 0:
print(a)
4개 이하의 조건이면 중복,반복 제거: 조건 and 사용
a, b = 10, 20
if a > b and a % 10 == 0:
print(a)
비트 연산자
a << b
a & b
a | b
a ^ b
상태를 나타내는 자료 활용하기
check = False
같은 조건 활용
나눠서 진행: 조건 판별을 다른 함수로 만들어버리는것도 좋음
def isPrime(N):
for i in range(2, N):
if N % i == 0:
return False
return True
for N in range(10, 100):
if isPrime(N):
print(“{} if Prime”.format(N))
else:
print(“not prime”)
ex) dfs/bfs: 조건을 반복문이 아닌 함수로 만들면 코드가 더 간결함
def isRange(a, b, N, M):
return 0 <= a < N and 0 <= b < M
여러 자료구조나 메서, 함수 활용
S = 'hello'
for i in S:
if S[i] != S[len(S)-i-1]:
print("not palin")
S = 'jello'
# reversing S
if S == S[::-1]:
print("not palin")
미리 처리한 케이스와 처리할 케이스 주석으로 정리
# 1. 예제 케이스
# 2. 조건 A
# 3. 조건 B
# 4. 조건 AB
def check(x):
pass
예제, 최소, 최대, 예외, 랜덤 케이스 만들기
상하좌우 (대표적) :쓰기편함 (빠름)
N | S | E | W | |
---|---|---|---|---|
x | -1 | 1 | 0 | 0 |
y | 0 | 0 | 1 | -1 |
dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]
x += dx['NSEW'.index(way)]
y += dy['NSEW'.index(way)]
반시계
| | E | N | W | S| |–|:–:|:–:|:–:|:–:| |x| 0| -1| 0| 1| |y| 1| 0| -1| 0|
dx = [0, -1, 0, 1]
dy = [1, 0 , -1, 0]
x += dx['ENSW'.index(way)]
y += dy['ENSW'.index(way)]
시계
| | E | S | W | N | |–|:–:|:–:|:–:|:–:| |x| 0| 1| 0|-1| |y| 1| 0| -1|0|
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
x += dx['ESWN'.index(way)]
y += dy['ESWN'.index(way)]
for i in range(4):
dfs(x + dx[i], y + dy[i])
BFS: Queue
DFS: Recursion (문제용으론 재귀가 더 편함) / Stack (이론적으론 스택을 사용)
대부분 DFS/BFS 둘다 사용해서 풀 수 있지만 둘중 하나만 써야만 풀 수 있는것도 있음
탐색의 2가지 핵심
: 상태에 대한 체크함수 필요
N차원 배열을 조정하는 방법
Flood fill
import sys
sys.setrecursion0limit(10000)
꼭 추가. 없으면 RE 발생할수있음
지도와 visited 는 global 선언
2 ways to present graph
[0]
/ |
7 5
/ |
[1] [2]
0 | 1 | 2 | |
---|---|---|---|
0 | 0 | 7 | 5 |
1 | 7 | 0 | inf |
2 | 5 | inf | 0 |
INF = 999999999
graph = [
[0, 7, 5],
[7, 0, INF],
[5, INF, 0]
]
print(graph) # [[0, 7, 5], [7, 0, 99999999], [5, 99999999, 0]]
print(graph[1][2]) # Faster speed
[0] -> [1(7)] -> [2(5)]
[1] -> [0(7)]
[2] -> [0(5)]
graph = [[] for _ in range(3)]
graph[0].append((1, 7))
graph[0].append((2, 5))
graph[1].append((0, 7))
graph[2].append((0, 5))
print(graph) # [[(1.7), (2.5)], [(0,7)], [(0,5)]]
# need iteration to find info1
패턴 찾는게 중요
import heapq
heapq.heapify(arr)
a = heapq.heappush(arr, i)
b = heapq.heappush(arr)
nCr = [sum(i) for i in list(itertools.combinations(C, 3)) if sum(i) <= M]
def union(x, y): x, y = find(x), find(y) parent[y] = x # 설정 방법은 문제 따라 다름 # number[x] += number[y] # 네트워크 크기 알고싶을 때
parent = [i for i in range(5)] union(1,4) union(2,4) for I in range(1, len(parent)): print(find(i), end=’ ‘)
- 프린터 q: 튜플, enum, lambda 활용
#### itertools 자주 쓰이는것들
| 예 | 결과 |
|---|:---|
product('ABCD', repeat=2) <br>모든거<br>n^r개 | AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD |
permutations('ABCD', r) <br>prod에서 자기자신 뺀거<br> nPr = n!/(n-r)! 개 | AB AC AD BA BC BD CA CB CD DA DB DC |
combinations('ABCD', r) <br>순서 노상관, 중복없음<br> nCr = n!/((n-r)!r!) 개 | AB AC AD BC BD CD |
combinations_with_replacement('ABCD', r) <br>comb 에서 자신 포함<br> (n+r-1)!/(r!(n-1)!) 개 | AA AB AC AD BB BC BD CC CD DD |
| 이터레이터 | 인자 | 결과 | 예 |
|---|---|---|---|
accumulate() | p [,func] | p0, p0+p1, p0+p1+p2, … | accumulate([1,2,3,4,5]) --> 1 3 6 10 15 |
chain() | p, q, … | p0, p1, … plast, q0, q1, … | chain('ABC', 'DEF') --> A B C D E F |
chain.from_iterable() | iterable | p0, p1, … plast, q0, q1, … | chain.from_iterable(['ABC', 'DEF']) --> A B C D E F |
compress() | data, selectors | (d[0] if s[0]), (d[1] if s[1]), … | compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F|
Reference: https://docs.python.org/ko/3/library/itertools.html
#### collections.Counter
- iterable 원소의 등장 횟수 세어줌
``` python
from collections import Counter
counter = Counter(['r', 'b', 'r', 'g', 'b'])
print(counter['b']) # 2
print(counter['g']) # 1
print(dict(counter)) # {'r':2, 'b':2, 'g':1}
from bisect import bisect_left, bisect_right
a = [1, 2, 4, 4, 9]
x = 4
print(bisect_left(a,x)) # 2
print(bisect_right(a,x)) # 4
def count_by_range(a, l, r): right_i = bisect_right(a, r) left_i = bisect_left(a, l) return right_i - left_i
a = [1, 2, 3, 3, 3, 3, 4, 4, 7, 8] print(count_by_range(a,4, 4)) # 2 print(count_by_range(a,-1, 3)) # 6 ```
Def | 특이점 | |
---|---|---|
BUB | for 0 to j-i-1, swap j, j+1 if j > j+1 | if swap == 0: break |
SEL | for i+1 to len - 1, search smallest, swap smallest, i | |
INS | from i + 1 to 0, swap j, j-1 if j < j-1 until j >= j-1 | if j >= j-1: break |
Recursive call | base case+ recursive case | act like stack Every recursion can be expressed w/ while loop |
DP | start solving from smallest prob, use its solution (saved for Memorization) for larger prob, therefore solve whole (going up) | small prob duplicate –> memoization ex) fibo |
D&C | divide prob until it cannot divide and conquer by merging together (going down) | small prob no duplicate use recursive call ex) QCK, MER |
QCK | set pivot, sort left, right | |
MER | 1. divde data by half until len == 1 2. recursively merge |
|
Graph | Node/Vertex + Edge | |
Degree: # connected nodes in undirected | ||
In-Degree: # incoming edges in directed | ||
Out-Degree: # outgoing edges in directed | ||
Path Length: # edges for path | ||
Simple path: startfinish path w/o node duplication | ||
Cycle: start == finish | ||
Acyclic graph: don’t have any cycle in undirected | ||
Complete graph: Every single node is connected to each other in undirected | ||
Undirected graph | A—B : (A, B), (B, A) | |
Connected Graph: Every node has path | ||
Disconnected Graph: Certain node does not have path | ||
Directed graph | A->B : <A, B> B->A : <B, A> |
|
Weighted graph / Network | Edge has weight | |
BFS | search same level first | |
DFS | search child node first |