- 2차원 배열
- 부분집합 생성
- Binary Search
- Selection Algorithm
- Selection sort
1차원 Array를 묶어놓은 Array
다차원 Array > 차원에 따라 Index를 선언
Python의 2차원 List:
arr = [[0, 1, 2, 3],
[4, 5, 6, 7]]
# row: 2, column: 42행 4열의 2차원 List
N, M = map(int, input().split())
# N: row M: column
arr = [list(map(int, input().split())) for _ in range(N)]
# list... 구문은 한 행, comprehension 구문은 필요 행만큼 반복arr2 = [[0] * M for _ in range(N)]
# cf. the code below is not working properly (it will use shallow copy)
arr2 = [[0] * M] * Nfor i in range(len(Array)):
# i행
for j in range(len(Array[i])):
# j열
Array[i][j] ~~~~
# i행 j열의 data
for i in range(N):
for j in range(M):
print(Array[i][j])for j in range(len(Array[0])):
for i in range(len(Array)):
Array[i][j]for i in range(len(Array)):
for j in range(len(Array[0])):
Array[i][j + (m-1-2*j) * (i % 2)]
# M-1-j // j
# i % 2: 홀짝판정어떻게 4방향의 인접 배열 요소를 탐색할까?
(i-1 i+1 j-1 j+1)
dx[] <- [0, 0, -1, 1]
dy[] <- [-1, 1, 0, 0] # 좌우상하
for x in range (len(ary)):
for y in range(len(ary[x])):
for I in range(4):
testX <- x + dx[mode]
testY <- y + dy[mode]
test(ary[testX][testY])
di = [0, 1, 0, -1]
dj = [1, 0, -1, 0]
for i in range(N):
for j in range(M):
for k in range(4):
ni = i + di[k]
nj = j + dj[k]
# 가장자리면 어떡해?
if 0 <= ni < N and 0 <= nj < M:
print(arr[ni][nj]) for i in range(N):
for j in range(M):
for di, dj in [[0, 1], [1, 0], [0, -1], [1-, 0]]:
ni = i + di
nj = j + dj
if 0 <= ni < N and 0 <= nj < M:
arr[ni][nj]arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for i in range(3):
for j in range(3):
if i < j:
# 반쪽...!
# 만일 이 과정을 생략한다면...? 도로 제자리로 돌겠지
arr[i][j], arr[j][i] = arr[j][i], arr[i][j]cf. [-7, -3, -2, 5, 8]에서, 합이 0이 되는 부분집합이 있을까? 있다면 몇 개일까?
- 완전검색 기법: 어떻게 부분집합을 만들까
- n elements: 2^n개의 부분집합이 생긴다
- 해당 element가 있는 경우 없는 경우 두 가지 & n개
bit = [0, 0, 0, 0]
for i in range(2):
bit[0] = i
for j in range(2):
bit[1] = j
for k in range(2):
bit[2] = k
for l in range(2):
bit[3] = l
print(bit)arr = [1, 2, 3, 4]
#### bit ####
for p in range(4):
if bit[p]:
print(arr[p], end= ' ')
print()& | << >> 비트 단위의 AND, OR, 좌/우 이동
뭐하러 [0, 0, 0, 0]...? 비트 단위로 저장해보자
1 << n : 2^n, 원소가 n개일 때의 모든 부분집합의 수
# bit 1을 n번 밀어
# ex
1 << 3 # 1이 8(2^3)로비트 사이에 AND와 OR 연산은 같은 비트 자리끼리만 수행됨
ex. AND
0 1 1 0 0 1
1 0 1 1 0 0
: 0 0 1 0 0 0
arr = [3, 6, 7, 1, 5, 4]
n = len(arr)
for i in range(1<<n):
for j in range(n):
# n만큼 bit를 비교할 것임
if i & (1<<j):
# i의 j번째 비트가 1이라면 arr[j] 출력
print(arr[j], end = ", ")
print()
print()비트 연산자n의 갯수가 바뀔 때 부분집합 문제를 유연하게 풀 수 있음
"저장된 자료 중에서 원하는 항목을 찾는 작업"
= 목적하는 탐색 키를 가진 항목을 찾는 것
- 순차검색
- 이진검색
- 해시
일렬로 되어 있는 자료를 순서대로 검색하는 방법
가장 간단, 직관적
배열이나 연결 리스트 등 순차구조로 구현된 자료구조에서 원하는 항목을 찾을 때 유용
구현이 쉽지만, 검색 대상의 수가 많다면 수행시간이 급격히 증가하여 비효율적
- 대상이 정렬되지 않은 경우
- 대상이 정렬된 경우
대상 key값 == 원소 key값 찾아 앞에서부터....
def search(A, N, key):
for i in range(N):
if A[i] == key:
return i
# return True
return -1
# return False찾고자 하는 원소의 순서에 따라 비교회수가 결정됨
시간 복잡도: O(n)
주의사항: and 문으로 인덱스 유효성 / 키값검사를 동시에 한다면, and 문의 앞부분을 유효성 검사로 해야 할 것 (먼저 검사하니까...!)
찾는 값보다 큰 값이 등장: 아 없구나: 종료
시간 복잡도: O(n) (여전히...)
하지만 검색 실패를 반환하는 경우 평균 비교 회수가 반으로 줄어든다.
def seqSearch(a n, key):
i <- 0
while 1 < n and a[i] < key:
# 다음으로
i <- i+1
if i < n and a[i] = key:
# 맞는 키를 찾아 나온 경우: 성공
return i
else:
# 지나가거나, 마지막 인덱스까지 다 뒤졌거나...
return -1
자료 가운데에 있는 항목의 키 값과 비교
반드시 정렬된 상태여야.
cf. 만일 자료에 추가삭제가 이뤄진다면 난감...
과정
- 중앙 원소 고르기
- 값 비교
- 작으면 왼쪽 반에서 다시, 크면 오른쪽 반에서 다시
- 찾을 때까지 1~3 반복
새 구간을 형성할 수 없다면 실패
- 검색범위의 시작점과 종료점을 이용하기
- 자료에 삽입이나 삭제가 발생했을 때 배열을 항상 정렬상태로 유지하는 작업이 필요
def binSearch(a, key)
start <- 0
end <- length(a) - 1
while start <= end:
# '=': 둘이 같더라도, 그 값이 찾는 값인가 한 번 확인은 해야 하니까
middle = (start + end) // 2
if a[middle] == key:
return True
# return middle
elif a[middle] > key:
end = middle - 1
else:
start = middle + 1
return False
def binarySearch(a, key):
start = 0
end = len(a) -1
while start <= end:
middle = (start + end) // 2
if a[middle] == key:
return middle
elif a[middle] > key:
end = middle - 1
else:
start = middle + 1
return -1def binSearch2(a, low, high, key):
if low > high:
return False
else:
middle = (low + high) // 2
if key == a[middle]:
return True
elif key < a[middle]:
return binSearch2(a, low, )테이블에 대한 동작 속도를 높여주는 자료 구조
key-field
대량 데이터의 성능저하 문제 해결을 위한 배열 인덱스
- 주어진 리스트 중 최소값을 찾는다
- 그 값을 리스트의 맨 앞에 위치한 값과 교환한다
- 맨 처음 위치를 제외한 나머지 리스트를 대상으로 위의 과정을 반복한다.
- 시간 복잡도: O(n^2)
- 구간 시작이 증가
def SelectionSort(a):
for i in range(0, len(a)-1):
# 구간의 시작
min = i
# 맨 앞을 제일 작다고 가정
for j in range(i+1, len(a)):
if a[min] > a[j]:
min = j
# if a[i] != a[min]을 만들면?
# 검사하는 과정이 길어져서... 그냥 바꾸자
a[i], a[min] = a[min], a[i]
# 치환과정참고: 버블정렬
for i : N-1 -> 1
for j : 0 -> i-1
if A[j] > A[j+1]
A[j] <-> A[j+1]
저장되어 있는 자료에서 k번째 큰/작은 원소를 찾는 방법
정렬 & 원소 접근
k가 비교적 작을 때 유용하며 O(kn)의 수행시간 필요
1번부터 k번째까지 작은 원소를 찾아 앞쪽으로 이동시키고 배열의 k번째를 반환 (어차피 그 뒤로는 필요없을테니)
cf. 나선채우기 문제
- [0, -1]에서 시작하기
- 가장자리 & 이미 채워진 곳
- 열+ / 행 + / 열 - / 행 - / 열+ ... (길이 감소)
dir = (dir +1) % 4
별첨
python에서의 a <= b <= c 비교
다른 언어에서는 a <= b True False 값을 <=와 비교하는 사태가 발생하기도 함