____________________________________________________________________________________________________________
3주차
이번 주 목표 : 스택, 큐의 개념과 활용법을 배운다. 해쉬 개념과 활용법에 대해 배운다. 트리, 힙의 개념과 활용법에 대해 배운다.
스택. 후입선출. Ctrl + Z 가 후입선출.
큐. 선입선출. 프로그래밍 언어의 컴파일링이 이런 방식. 자바스크립트가 그래.
________________________________________________
3-2 정렬-1
정렬이란? 그리고 버블 정렬이란?
파일 : sparta_algorithm - week_3 - 01_bubble_sort.py
버블 정렬을 직접 구현해보자.
——
def bubble_sort(array):
for all_i in range(len(array) -1): # 예를 들어 len(arr)가 5다, 그럼 4번만 반복 해주면 가장 작은 숫자가 맨 앞으로 어차피 오게 되어 있어.
for i in range(len(array) - 1 - all_i): # i와 i+1 을 비교해. 그래서 마지막 i 는 비교 하지 않아도 돼.
if array[i] > array[i + 1]: # 또한, 매번 가장 큰 수를 맨 뒤로 보내고 있는데, 맨 뒤로 보낸 수는 다음 for 때는 고려할 필요가 없어.
array[i], array[i + 1] = array[i + 1], array[i]
return array
input = [4, 6, 2, 9, 1]
bubble_sort(input)
print(input) # [1, 2, 4, 6, 9] 가 되어야 합니다!
print("정답 = [1, 2, 4, 6, 9] / 현재 풀이 값 = ",bubble_sort([4, 6, 2, 9, 1]))
print("정답 = [-1, 3, 9, 17] / 현재 풀이 값 = ",bubble_sort([3,-1,17,9]))
print("정답 = [-3, 32, 44, 56, 100] / 현재 풀이 값 = ",bubble_sort([100,56,-3,32,44]))
——
=> 음… 잘은 모르겠지만, 시간 복잡도가 어림잡아 N의 제곱은 되는 것 같아. 뭔가.. 더 개선할 방법이 있을 거 같은데?
________________________________________________
3-3 정렬-2
또 다른 정렬의 방법 중 하나인 <선택 정렬> 과 <삽입 정렬> 에 대해서 알아보자.
우선, <선택 정렬>
=> 예를 들어서, 배열의 요소들을 다 비교해서 가장 작은 숫자를 0번째 인덱스로,
그 다음 0번째 인덱스를 제외하고 나머지 배열의 원소들을 비교해서 가장 작은 숫자를 1번째 인덱스로,
그 다음 0, 1번째 인덱스를 제외하고…
이런 식으로, ‘가장 작은 원소’ 를 하나 콕 찝어서 한 구석으로 배치하고는 다음 비교땐 배치했던 원소를 제외하고 다시 비교하는 식.
전체를 비교해서 한 놈을 콕 찝어서 재배치하고 제외, 이런 식이 선택 정렬.
파일 : sparta_algorithm - week_3 - 02_selection_sort.by
——
print('---------- 내가 시도해 본 것 ----------')
def selection_sort(array):
for all_i in range(len(array) - 1): # 1
min_index = all_i
for i in range(all_i, len(array)): # 1, 2, 3, 4
if array[min_index] > array[i]:
min_index = i
array[all_i], array[min_index] = array[min_index], array[all_i]
return array
input = [4, 6, 2, 9, 1] # [1, 6, 2, 9, 4]
selection_sort(input)
print(input) # [1, 2, 4, 6, 9] 가 되어야 합니다!
print("정답 = [1, 2, 4, 6, 9] / 현재 풀이 값 = ",selection_sort([4, 6, 2, 9, 1]))
print("정답 = [-1, 3, 9, 17] / 현재 풀이 값 = ",selection_sort([3,-1,17,9]))
print("정답 = [-3, 32, 44, 56, 100] / 현재 풀이 값 = ",selection_sort([100,56,-3,32,44]))
print('---------- 튜터님의 답 ----------')
def selection_sort(array):
n = len(array)
for i in range(n - 1):
min_index = i
for j in range(n - i): # 5-0 5-1 5-2 5-3 // 5, 4, 3, 2 // i => 00000 1111 222 33 j => 01234 0123 012 01 출력
if array[i + j] < array[min_index]:
min_index = i + j
array[min_index], array[i] = array[i], array[min_index]
return array
input = [4, 6, 2, 9, 1]
selection_sort(input)
print(input) # [1, 2, 4, 6, 9] 가 되어야 합니다!
print("정답 = [1, 2, 4, 6, 9] / 현재 풀이 값 = ",selection_sort([4, 6, 2, 9, 1]))
print("정답 = [-1, 3, 9, 17] / 현재 풀이 값 = ",selection_sort([3,-1,17,9]))
print("정답 = [-3, 32, 44, 56, 100] / 현재 풀이 값 = ",selection_sort([100,56,-3,32,44]))
——
=> 내가 시도하는 건, 중첩 for문이 돌 때마다 시작 인덱스를 증가시키는 것.
튜터님의 코드는 중첩 for문이 돌 때마다 시작 인덱스는 0이되 돌아가는 횟수를 줄이고, i + j 를 함으로써 시작 인덱스를 증가시켜주셨어.
다음으로 <삽입 정렬>
=> <선택 정렬>이 전체에서 최솟값을 선택해서 앞으로 당겨오는 것이라면,
<삽입 정렬>은 전체에서 하나를 올바른 위치에 ‘삽입’ 하는 방식.
선택 정렬은 해당 인덱스의 요소값이 비교 대상보다 높든 낮든 항상 비교하고 위치를 바꾸지만,
삽입 정렬은 필요한 때만 위치를 변경하므로 시간 복잡도 면에서 더 효율적인 방식.
파일 : sparta_algorithm - week_3 - 03_insertion_sort.py
——
print('---------- 내가 시도해 본 것 ----------')
def insertion_sort(array):
n = len(array)
for all_i in range(n - 1): # 0, 1, 2, 3
for i in range(all_i + 1): # 0 / 0, 1 / 0, 1, 2 / 0, 1, 2, 3
if array[all_i - i] > array[all_i + 1 - i]: # 3, 4 -> 2, 3
array[all_i - i], array[all_i + 1 - i] = array[all_i + 1 - i], array[all_i - i]
else:
break
return array
input = [4, 6, 2, 9, 1]
insertion_sort(input)
print(input) # [1, 2, 4, 6, 9] 가 되어야 합니다!
print("정답 = [4, 5, 7, 7, 8] / 현재 풀이 값 = ",insertion_sort([5,8,4,7,7]))
print("정답 = [-1, 3, 9, 17] / 현재 풀이 값 = ",insertion_sort([3,-1,17,9]))
print("정답 = [-3, 32, 44, 56, 100] / 현재 풀이 값 = ",insertion_sort([100,56,-3,32,44]))
print('---------- 튜터님의 답 ----------')
def insertion_sort2(array):
n = len(array) # 5
for i in range(1, n): # # 왜 1부터 시작하는가. 배열의 0번째 요소는 이미 정렬이 되어있다 라고 치기 때문에, 있지도 않은 이전 요소와 비교할 필요가 없어.
for j in range(i):
if array[i - j - 1] > array[i - j]:
array[i - j - 1], array[i - j] = array[i - j], array[i - j - 1]
return array
input2 = [4, 6, 2, 9, 1]
insertion_sort2(input2)
print(input) # [1, 2, 4, 6, 9] 가 되어야 합니다!
print("정답 = [4, 5, 7, 7, 8] / 현재 풀이 값 = ",insertion_sort2([5,8,4,7,7]))
print("정답 = [-1, 3, 9, 17] / 현재 풀이 값 = ",insertion_sort2([3,-1,17,9]))
print("정답 = [-3, 32, 44, 56, 100] / 현재 풀이 값 = ",insertion_sort2([100,56,-3,32,44]))
——
=> 작동 원리는 같아. Index를 매겨주는 방법이 조금 다를 뿐.
헌데 배열의 첫 요소를 이전 요소와 비교할 필요가 없다, 는 점에서는 알고리즘 제작의 취지에는 튜터님의 함수가 더욱 잘 어울려.
즉, ‘보다 뒤에 있는 것’ 을 잡고, ‘한 칸 앞에 있는 것과 비교’ 한다는 부분,
예를 들면, input 배열의 경우에는 ‘가장 처음에는 6을 잡고, -1 인 4와 비교하겠다’ 라는 취지인거지.
________________________________________________
3-4 정렬-3. 병합 정렬
<병합 정렬> 에 대해서 배워볼거야.
병합 정렬은 배열의 앞부분과 뒷부분의 두 그룹으로 나누어 각각 정렬한 후 병합하는 작업을 반복하는 알고리즘.
우선 병합 정렬 - merge 에 대해서.
파일 : sparta_algorithm - week_3 - 04_merge.py
——
def merge(array1, array2):
array_c = []
array1_index = 0
array2_index = 0
while array1_index < len(array1) and array2_index < len(array2): # 둘 중 하나는 모조리 다 array_c 에 들어가. 남는 건?
if array1[array1_index] < array2[array2_index]:
array_c.append(array1[array1_index])
array1_index += 1
else:
array_c.append(array2[array2_index])
array2_index += 1
if array1_index == len(array1): # 만약 array1 의 요소=원소들이 다 array_c 로 넘어가서, index 카운트가 len 만큼 찼다면?
while array2_index < len(array2):
array_c.append(array2[array2_index])
array2_index += 1
if array2_index == len(array2): # 만약 array2 의 요소=원소들이 다 array_c 로 넘어가서, index 카운트가 len 만큼 찼다면?
while array1_index < len(array1):
array_c.append(array1[array1_index])
array1_index += 1
return array_c
array_a = [1, 2, 3, 5]
array_b = [4, 6, 7, 8]
print(merge(array_a, array_b)) # [1, 2, 3, 4, 5, 6, 7, 8] 가 되어야 합니다!
print("정답 = [-7, -1, 5, 6, 9, 10, 11, 40] / 현재 풀이 값 = ", merge([-7, -1, 9, 40], [5, 6, 10, 11]))
print("정답 = [-1, 2, 3, 5, 10, 40, 78, 100] / 현재 풀이 값 = ", merge([-1,2,3,5,40], [10,78,100]))
print("정답 = [-1, -1, 0, 1, 6, 9, 10] / 현재 풀이 값 = ", merge([-1,-1,0], [1, 6, 9, 10]))
——
=> 사실 이건, 이미 정렬되어 있는 두 개의 배열을 그냥 ‘병합’ 한 것에 지나지 않아.
다음으로, 병합 정렬 - mergeSort 에 대해서.
=> mergeSort 는 단순히 merge 하는 것 뿐 만 아니라, 합치면서 정렬하는 방법.
병합 정렬, 합치면서 정렬은 어떻게 하는가?
=> 분할 정복의 개념을 적용.
문제를 작은 2개의 문제로 분리하고 각각을 해결한 다음, 결과를 모아서 원래의 문제를 해결하는 전략.
merge_sort 에는 재귀 함수 사용.
파일 : sparta_algorithm - week_3 - 05_merge_sord.py
——
def merge_sort(array):
if len(array) <= 1:
return array
mid = len(array) // 2
left_array = merge_sort(array[:mid])
right_array = merge_sort(array[mid:])
return
def merge(array1, array2):
.
.
.
——
=> 재귀 함수는, 기본적으로는
가지가 나무 마냥 쭉쭉 사방으로 뻗어서 코드가 완성되고 난 후, 그 때부터 실행 되면서
하나의 뿌리로 거슬러 올라가듯이 작동해. 즉 각각의 나뭇가지 부터가 실행되고, 거슬러 올라가듯 처음으로 돌아와서는
뿌리의 코드를 가장 마지막에 실행해.
merge_sort 의 경우는 배열의 요소들을 모두 하나씩 하나씩 분해한 다음, merge 로 합치면서 거슬러 올라와.
________________________________________________
3-5 스택
스택이란?
=> 한 쪽 끝으로만 자료를 넣고 뺄 수 있는 자료구조. 선입후출. 즉 후입선출.
스택 자료구조는 데이터를 넣고 빼고 하는 게 잦기 때문에 링크드 리스트와 유사하게 구현할 수 있어.
스택이라는 자료구조에서 제공하는 기본적인 기능은 다음과 같아.
push(data) : 맨 앞에 데이터 넣기
pop() : 맨 앞의 데이터 뽑기
peek() : 맨 앞의 데이터 보기
isEmpty(): 스택이 비었는지 안 비었는지 여부 반환해주기
스택 구조 만들어보기.
파일 : sparta_algorithm - week_3 - 06_stack.py
——
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Stack:
def __init__(self):
self.head = None
# push. 맨 앞에 데이터 넣기.
def push(self, value): # 만약 처음에 [4] 만 있었다면, [3] -> [4] 이렇게 만들어주는 거지. head 자리를 새치기 하는거야. 왜? 후입선출.
new_head = Node(value)
new_head.next = self.head # 먼저 기존의 head 를 새로운 node 의 next 에 연결 해주고
self.head = new_head # 새로 입력한 node 를 head 로 선정.
# pop. 맨 앞의 데이터를 지우 면서 리턴으로 가져옴.
def pop(self):
if self.is_empty(): # 스택이 비어있다면?
return "현재 스택에는 아무것도 저장되어 있지 않습니다."
delete_head = self.head
self.head = self.head.next
return delete_head
# peek. 맨 앞의 데이터 보기.
def peek(self):
if self.is_empty():
return "현재 스택에는 아무것도 저장되어 있지 않습니다."
return self.head.data
# isEmpty. 스택이 비었는지 안 비었는지 여부를 판별.
def is_empty(self):
return self.head is None # None 이라면 비어 있으니까 true 를 반환 하겠지. 있으면 false 를 반환하고.
stack = Stack()
stack.push(3)
print(stack.peek())
stack.push(4)
print(stack.peek())
stack.push(5)
print(stack.pop().data)
print('가장 위에 있는 스택은? ', stack.peek())
print('현재 스택은 비어있는가? ', stack.is_empty())
——
=> 마지막에 들어온 노드가 가장 위에, 즉 Head가 된다.
스택 구조에 대한 기본적인 지식을 알아봤으니, 실전 문제를 풀어보자.
파일 : sparta_algorithm - week_3 - 07_get_receiver_top_orders.py
문제. Q. 수평 직선에 탑 N대를 세웠습니다. 모든 탑의 꼭대기에는 신호를 송/수신하는 장치를 설치했습니다.
발사한 신호는 신호를 보낸 탑보다 높은 탑에서만 수신합니다. 또한 ,한 번 수신된 신호는 다른 탑으로 송신되지 않습니다.
예를 들어 높이가 6, 9, 5, 7, 4 인 다섯 탑이 왼쪽으로 동시에 레이저 신호를 발사합니다. 그러면, 탑은 다음과 같이 신호를 주고 받습니다.
높이가 4인 다섯 번째 탑에서 발사한 신호는 높이가 7인 네 번째 탑에서 수신하고, 높이가 7인 네 번째 탑의 신호는 높이가 9인 두 번째 탑이,
높이가 5인 세 번째 탑의 신호도 높이가 9인 두 번째 탑이 수신합니다.
높이가 9인 두 번째 탑과 높이가 6인 첫 번째 탑이 보낸 레이저 신호는 어떤 탑에서도 수신할 수 없습니다.
이 때, 맨 왼쪽부터 순서대로 탑의 높이를 담은 배열 heights가 매개변수로 주어질 때 각 탑이 쏜 신호를 어느 탑에서 받았는지 기록한 배열을 반환하시오.
——
def get_receiver_top_orders(heights):
result_arr = [0] * len(heights) # 결과값을 담을 배열을 만들어 놔. 0으로 초기화한 이유는,
# 어차피 레이저가 가로막히지 않는다면 송신해 줄 수 있는 탑이 없다는 뜻이니.
while heights: # heights 전체를 하나의 스택 구조라 한다면, 내부의 요소들은 모두 쌓인 스택들.
# pop 으로 마지막 요소를 매번 제거해줄거야. height 가 빈 상태가 되면 while문이 종료.
height = heights.pop() # 배열의 마지막, 그니까 후입선출에 의거하여 배열의 마지막 요소를 제거하고는 리턴.
for i in range(len(heights) -1, 0, -1): # range(a, b, c) a = 시작하는 점, b = 끝나는 점, c = 매번 연산을 얼마나 줄일 것인가.
# 왜 len(heights) - 1 부터 인가. 배열의 마지막 요소를 이미 pop 했으니까.
if heights[i] > height: # 만약 전파가 막힌다면?
result_arr[len(heights)] = i + 1 # 어차피 pop 으로 길이가 줄어들어서 바로 길이를 인덱스에 넣어도 돼.
# 현재 남아있는 길이가 pop 의 인덱스 번째야.
# 그리고, pop 한 배열의 마지막 요소가 어디에서 막혔는가, heights[i]번째 탑에서 막혔다.
# i는 0부터 시작한 인덱스 값이고, 물리적인 탑의 순서를 나타내주기 위래선 + 1 해줘야지.
break # 전파가 이미 가로 막혔으니, 더 이상 앞쪽 인덱스들과 크기를 비교하지 않아도 돼.
return result_arr
top_heights = [6, 9, 5, 7, 4]
print(get_receiver_top_orders(top_heights)) # [0, 0, 2, 2, 4] 가 반환되어야 한다!
print("정답 = [0, 0, 2, 2, 4] / 현재 풀이 값 = ",get_receiver_top_orders([6,9,5,7,4]))
print("정답 = [0, 0, 0, 3, 3, 3, 6] / 현재 풀이 값 = ",get_receiver_top_orders([3,9,9,3,5,7,2]))
print("정답 = [0, 0, 2, 0, 0, 5, 6] / 현재 풀이 값 = ",get_receiver_top_orders([1,5,3,6,7,6,5]))
——
3-5_2 추가문제. 스택 수열.
________________________________________________
3-6 큐
큐 란?
=> 한 쪽 끝으로 자료를 넣고, 반대 쪽에서는 자료를 빼는 선형적인 구조. 선입선출. 후입후출.
큐 라는 자료구조는 왜 필요한가? 순서대로 일을 처리해야 하기 때문.
예를 들어, 가게에 주문이 들어오면, 주문을 먼저 한 순서대로 처리해야 해.
큐 라는 자료구조에서 제공하는 기능은 다음과 같아.
enqueue(data) : 맨 뒤에 데이터 추가하기
dequeue() : 맨 앞의 데이터 뽑기
peek() : 맨 앞의 데이터 보기
isEmpty(): 큐가 비었는지 안 비었는지 여부 반환해주기
큐 구현해보기.
파일 : sparta_algorithm - week_3 - 08_queue.py
——
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Queue:
def __init__(self):
self.head = None
self.tail = None
# 맨 뒤에 데이터 추가하기
def enqueue(self, value):
new_node = Node(value)
if self.is_empty():
self.head = new_node
self.tail = new_node
return
self.tail.next = new_node # 기존의 self.tail에 저장되어 있던 노드에게 next 로 new_node 를 설정해주고
self.tail = new_node # self.tail 에는 new_node의 래퍼런스를 저장.
return
# 맨 앞의 데이터 뽑기. 선입 선출.
def dequeue(self):
if self.is_empty():
return "queue is empty"
dequeue_node = self.head
self.head = self.head.next
return dequeue_node.data
# 맨 앞의 데이터 보기
def peek(self):
if self.is_empty():
return "queue is empty"
return self.head.data
# 큐가 비었는지 안 비었는지 여부
def is_empty(self):
return self.head is None
queue = Queue()
queue.enqueue(3)
print(queue.peek())
queue.enqueue(4)
print(queue.peek())
queue.enqueue(5)
print(queue.peek())
print('--- 선입선출로 잘 빠져 나오나? ---')
print(queue.dequeue())
print(queue.peek())
print(queue.is_empty())
——
________________________________________________
3-7 해쉬 - 1
해쉬 란?
=> 컴퓨팅에서 키를 값에 매핑할 수 있는 구조인, 연관 배열 추가에 사용되는 자료 구조이다.
해시 테이블은 해시 함수를 사용하여 색인(index)을 버킷(bucket)이나 슬롯(slot)의 배열로 계산한다.
데이터를 다루는 기법 중에 하나로 데이터의 검색과 저장이 아주 빠르게 진행된다.
뭐, 뭔?
중요한 건, 데이터의 검색과 저장이 아주 빠르게 진행된다는 장점을 가지고 있다는 것만 알고 있으면 돼.
파이썬에서는 딕셔너리와 해쉬 테이블이 동일하다 라고 보면 되긴 해….
헌데, 딕셔너리는 사실 내부적으로는 배열을 사용하고 있어.
그럼 해쉬를 사용해서 딕셔너리를 구현해보자.
파일 : sparta_algorithm - week_3 - 09_dict.py
——
print('--------------------------- 3-7 해쉬-1 딕셔너리 구현해보기 ---------------------------')
class Dict:
def __init__(self):
self.items = [None] * 8
def put(self, key, value):
idx_key = hash(key) % len(self.items) # 나머지를 이용하는 거잖아. 따라서 무조건 배열의 길이 미만으로 값이 나오지. 그걸 인덱스로 이용.
self.items[idx_key] = value
return
def get(self, key):
idx = hash(key) % len(self.items)
return self.items[idx]
my_dict = Dict()
my_dict.put("test", 3)
print(my_dict.get("test")) # 3이 반환되어야 합니다!
——
=> 문제가 하나 있어. 바로 ‘충돌’ 문제.
만약 해쉬에 사용하는 키가 달라도 같은 인덱스를 출력할 수 있잖아?
그럴 때에는 같은 인덱스 값이 나와도 괜찮도록 애당초 해당 인덱스에 ‘링크드 리스트’, 즉 노드의 형태로 값을 저장해 두는거지.
해쉬값의 충돌을 대비하여, 링크드 리스트의 형태로 자료를 저장해 보자.
파일 : sparta_algorithm - week_3 - 10_linked_dict.py
——
class LinkedTuple:
def __init__(self):
self.items = list()
def add(self, key, value):
self.items.append((key, value))
def get(self, key):
for k, v in self.items:
print('k, v : ', k, v)
if key == k:
return v
class LinkedDict:
def __init__(self):
self.items = []
for i in range(8):
self.items.append(LinkedTuple()) # [ [ (key, value), (key, value) ], [], [], [], [], [], [], [] ]
def put(self, key, value):
hash_idx = hash(key) % len(self.items)
self.items[hash_idx].add(key, value)
def get(self, key):
hash_idx = hash(key) % len(self.items)
return self.items[hash_idx].get(key)
linkedDict = LinkedDict()
linkedDict.put("test", 33)
linkedDict.put("test", 34)
linkedDict.put("test", 35)
print(linkedDict.get("test"))
print(linkedDict.items[7])
——
=> 이 외에도 hash + key 값으로 얻은 인덱스 위치에 이미 데이터가 존재할 경우, 다음 인덱스에 데이터를 저장하는 “개방 주소법” 등,
충돌을 피하기 위한 여러 가지 방법이 존재해.
3-8 해쉬-2
해쉬 관련 개념을 정리하고, ‘출석체크’ 라는 문제를 풀면서 해쉬를 어떻게 쓰면 좋을지에 대해 알아보자.
해쉬 테이블(Hash Table)은 "키" 와 "데이터"를 저장함으로써 즉각적으로 데이터를 받아오고 업데이트하고 싶을 때 사용하는 자료구조입니다.
해쉬 함수(Hash Function)는 임의의 길이를 갖는 메시지를 입력하여 고정된 길이의 해쉬값을 출력하는 함수입니다.
해쉬 테이블의 내부 구현은 키를 해쉬 함수를 통해 임의의 값으로 변경한 뒤 배열의 인덱스로 변환하여 해당하는 값에 데이터를 저장합니다.
그렇기 때문에 즉각적으로 데이터를 찾고, 추가할 수 있는 것 입니다. 만약, 해쉬 값 혹은 인덱스가 중복되어 충돌이 일어난다면?
체이닝과 개방 주소법 방법으로 해결할 수 있습니다!
출석 체크 문제 풀어보기.
파일 : sparta_algorithm - week_3 - 11_get_absent_student.py
——
all_students = ["나연", "정연", "모모", "사나", "지효", "미나", "다현", "채영", "쯔위"]
present_students = ["정연", "모모", "채영", "쯔위", "사나", "나연", "미나", "다현"]
def get_absent_student(all_array, present_array):
student_dict = {}
result_arr = []
for student in all_array:
student_dict[student] = 1 # JS 마냥 객체.key 이렇게 선언해 주기만 해도 키가 추가 돼.
for key in present_array:
del student_dict[key] # student_dict 딕셔너리의 해당 key 를 키값과 함께 제거.
for key in student_dict:
result_arr.append(key) # 모든 학생 명단에서 출석한 학생만 지웠어. 남은 건 출석하지 않은 학생들. 그들을 따로 배열에 담아.
return result_arr
print(get_absent_student(all_students, present_students))
print("정답 = 예지 / 현재 풀이 값 = ",get_absent_student(["류진","예지","채령","리아","유나"],["리아","류진","채령","유나"]))
print("정답 = RM / 현재 풀이 값 = ",get_absent_student(["정국","진","뷔","슈가","지민","RM"],["뷔","정국","지민","진","슈가"]))
——
'내일배움캠프_개발일지 > 프로그래밍 기초_알고리즘' 카테고리의 다른 글
프로그래밍 기초_알고리즘 5 (2) | 2022.11.29 |
---|---|
프로그래밍 기초_알고리즘 4 (0) | 2022.11.25 |
프로그래밍 기초_알고리즘 2 (0) | 2022.11.23 |
프로그래밍 기초_알고리즘 1 (0) | 2022.11.22 |