원하는 데이터
를 찾는 과정stack = []
# 삽입5, 삽입2, 삽입3, 삽입7, 삭제, 삽입1, 삽입4, 삭제
stack.append(5)
stack.append(2)
stack.append(3)
stack.append(7)
stack.pop()
stack.append(1)
stack.append(4)
print(stack[::-1]) # 최상단 원소부터 출력
print(stack) # 최하단 원소부터 출력
from collections import deque
# 큐 구현을 위해 deque 라이브러리 사용
queue = deque()
# 삽입5, 삽입2, 삽입3, 삽입7, 삭제, 삽입1, 삽입4, 삭제
queue.append(5)
queue.append(2)
queue.append(3)
queue.append(7)
queue.poplefet(1)
queue.append(1)
queue.poplefet()
print(queue) # 먼저 들어온 순서대로 출력
queue.reverse() # 연숙으로 출력
print(queue) # 나중에 들어온 원소부터 출력
##실행결과
# deque([3,7,1,4])
# deque([4,7,1,3])
재귀함수(Recursive Function)란 자기 자신을 다시 호출하는 함수를 의미
단순한 형태의 재귀 함수 예제
def recursive_func():
print('call recursive function')
recursive_function()
recursive_function()
0 + 1
== 1이 되고 --> 다시 호출했던 recur(1) 이는 1+1
이 되어 def recursive_function(i):
# 100번째 호출을 했을 시 종료 되도록 종료 조건 명시
if i ==100:
return
print(i, '번째 재귀함수에서', i+1, '번째 재귀함수를 호출합니다.')
recursive_function(i+1)
print(i, '번째 재귀함수를 종료합니다.')
recursive_function(1)
# 반복적으로 구현한 n!
def factorial_iterative(n):
result = 1
# 1부터 n까지의 수를 차례대로 곱하기
for i in range(1, n +1):
result *= i
return result
# 재귀적으로 구현한 n!
def factorial_recursive(n):
if n <= i: # n이 1 이하인 경우 1을 반환
return 1
# n! = n * (n - 1)!를 그대로 코드로 작성
return n * factorial_recursive(n - 1)
# 각각의 방식으로 구현한 n! 출력n=5)
print('반복적으로 구현:', factorial_iterative(5))
print('반복적으로 구현:', factorial_iterative(5))
유클리드 호제법
def gcd(a,b):
if a%b ==0:
return b
else:
return gcd(b, a % b)
print(gcd(192, 162))
재귀 함수는 반복문을 이용하여 동일한 기능을 구현
하나, 그래프를 준비
방문기준 : 번호가 낮은 인접노드 부터
시작노드 : 1
둘, 시작 노드인 '1'을 스택에 삽입하고 방문 처리를 합니다.
셋, 스택의 최상단 노드인 '1'에 방문하지 않은 인접 노드 '2', '3', '8'이 있습니다.
넷, 스택의 최상단 노드인 '2'에 방문하지 않은 인접 노드 '7'이 있습니다.
다섯, 스택의 최상단 노드인 7에 방문하지 않은 인접 노드 6, 8이 있습니다
이러한 과정을 반복하였을 때 전체 노드의 탐색 순서(스택에 들어간 순서)는 다음과 같습니다.
# DFS메서드 정의
def dfs(graph, v, visited):
# 현제 노드를 방문 처리
visited[v] = True
print(v, end=' ')
# 현재 노드와 연결된 다른 노드를 재귀적으로 방문
for i in graph[v]:
if not visited[i]:
dfs(graph, i, visited)
# 각 노드가 연결된 정보를 표현(2차원 리스트)
graph = [
[],
[2,3,8],
[1,7],
[1,4,5],
[3,5],
[3,4],
[7],
[2,6,8],
[1,7],
]
# 각 노드가 방문된 정보를 표현 (1차원 리스트)
visited = [False] * 9
# 정의된 DFS 함수 호출
dfs(graph, 1, visited)
그래프를 준비합니다.(방문기준: 번호가 낮은 인접노드부터)
시작 노드인 1을 큐에 삽입하고 방문처리를 합니다.
큐에서 노드 1을 꺼내 방문하지 않은 인접 노드 2,3,8을 큐에 삽입하고 방문 처리를 합니다.
큐에서 노드 2를 꺼내 방문하지 않은 인접 노드 7을 큐에 삽입하고 방문 처리합니다.
큐에서 노드 3을 꺼내 방문하지 않은 인접 노드 4, 5를 큐에 삽입하고 방문 처리합니다.
큐에서 8을 꺼내고 방문하지 않은 인접 노드가 없으므로 무시합니다.
이러한 과정을 반복하여 전체 노드의 탐색 순서(큐에 들어간 순서)는 아래와 같아요.
from collections import deque
# BFS 메서드 정의
def bfs(graph, start, visited):
# queue 구현을 위해 deque 라이브러리 사용
queue = deque([start])
# 현재 노드를 방문 처리
visited([start]) = True
# 큐가 빌 때까지 반복
while deque:
# 큐에서 하나의 원소를 뽑아 출력하기
v = queue.popleft()
print(v, end=' ')
# 아직 방문하지 않은 인접한 원소들을 큐에 삽입
for i in graph[v]:
if not visited[i]:
queue.append(i)
visited[i] = True
# 각 노드가 연결된 정보를 표현 (2차원 리스트)
graph = [
[],
[2,3,8],
[1,7],
[1,4,5],
[3,5],
[3,4],
[7],
[2,6,8],
[1,7],
]
# 각 노드가 방문된 정보를 표현 (1차원 리스트)
visited =[False] * 9
# 정의된 BFS 함수 호출
bfs(graph, 1, visited)
# 출력 결과
# 1 2 3 8 7 4 5 6
이 문제는 DFS 혹은 BFS로 해결할 수 있습니다. 일단 앞에서 배운 대로 얼음을 얼릴 수 있는 공간이 상,하,좌,우로 연결되어 있다고 표현할 수 있으므로 그래프 형태로 모델링 할 수 있습니다. 다음과 같이 3 * 3크기의 얼음 틀이 있다고 가정하고 생각해 봅시다.
def dfs(x,y):
if x<=-1 or x>=n or y<=-1 or y >=m:
return False
if graph[x][y] == 0:
graph[x][y] = 1
dfs(x-1,y)
dfs(x,y-1)
dfs(x+1,y)
dfs(x,y+1)
return True
return False
n, m = map(int, input().split())
graph = []
for i in range(n):
graph.append(list(map(int, input())))
result = 0
for i in range(n):
for j in range(m):
if dfs(i, j) == True:
result += 1
print(result)
아래 부분은 리턴값을 가지지 않고 단순히 방문처리를 위한 목적으로 사용됨
dfs(x-1,y)
dfs(x,y-1)
dfs(x+1,y)
dfs(x,y+1)
처음에 (1,1)의 위치에서 시작합니다.
(1,1) 좌표에서 상하좌우로 탐색을 진행하면 바로 옆 노드인(1,2) 위치의 노드를 방문하게 되고 새롭게 방문하는 (1,2) 노드의 값을 2로 바꾸게 됩니다.
# bfs 소스코드 구현
def bfs(x,y):
# 큐 구현을 위해 deque 라이브러리 사용
queue = deque()
queue.append((x,y))
# 큐가 빌 때까지 반복
while queue:
x,y = queue.popleft()
# 현재 위치에서 4가지 방향으로 위치 확인
for i in range(4):
nx = x + dx[i]
ny = x + dy[i]
# 미로 찾기 공간을 벗어난 경우 무시
if nx < 0 or nx >=n or ny < 0 or ny >=m:
continue
# 벽인 경우 무시
if graph[nx][ny] == 0:
continue
# 해당 노드를 처음 방문하는 경우에만 최단 거리 기록
if graph[nx][ny] == 1:
graph[nx][ny] = graph[x][y] + 1
queue.append((nx, ny))
# 가장 오른쪽 아래까지의 최단 거리 반환
return graph[n-1][m-1]
from collections import deque
n,m = map(int, input().split())
graph = []
for i in range(n):
graph.append(list(map(int, input())))
dx = [-1,1,0,0]
dy = [-1,1,0,0]
print(bfs(0,0))