mirror of
https://github.com/krahets/hello-algo.git
synced 2026-11-02 03:05:24 +08:00
feat(ko): add the Korean online edition (#2006)
* feat(ko): add the complete Korean online edition * Use UTF-8 for Python CI output on Windows * Remove print-book promotion from the Korean site * fix(ko): preserve emphasis before Korean particles
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
"""
|
||||
File: array.py
|
||||
Created Time: 2022-11-25
|
||||
Author: krahets ([email protected])
|
||||
"""
|
||||
|
||||
import random
|
||||
|
||||
|
||||
def random_access(nums: list[int]) -> int:
|
||||
"""원소에 임의 접근"""
|
||||
# 구간 [0, len(nums)-1]에서 숫자 하나를 무작위로 뽑는다
|
||||
random_index = random.randint(0, len(nums) - 1)
|
||||
# 무작위 원소를 가져와 반환한다
|
||||
random_num = nums[random_index]
|
||||
return random_num
|
||||
|
||||
|
||||
# Python의 list는 동적 배열이므로 직접 확장할 수 있다
|
||||
# 학습의 편의를 위해 이 함수에서는 list를 길이가 고정된 배열로 취급한다
|
||||
def extend(nums: list[int], enlarge: int) -> list[int]:
|
||||
"""배열 길이 확장"""
|
||||
# 길이를 확장한 배열을 초기화한다
|
||||
res = [0] * (len(nums) + enlarge)
|
||||
# 원래 배열의 모든 원소를 새 배열에 복사한다
|
||||
for i in range(len(nums)):
|
||||
res[i] = nums[i]
|
||||
# 확장한 새 배열을 반환한다
|
||||
return res
|
||||
|
||||
|
||||
def insert(nums: list[int], num: int, index: int):
|
||||
"""배열의 인덱스 index에 원소 num 삽입"""
|
||||
# 인덱스 index와 그 뒤에 있는 모든 원소를 한 칸씩 뒤로 이동한다
|
||||
for i in range(len(nums) - 1, index, -1):
|
||||
nums[i] = nums[i - 1]
|
||||
# index 위치의 원소에 num을 대입한다
|
||||
nums[index] = num
|
||||
|
||||
|
||||
def remove(nums: list[int], index: int):
|
||||
"""인덱스 index에 있는 원소 삭제"""
|
||||
# 인덱스 index 뒤에 있는 모든 원소를 한 칸씩 앞으로 이동한다
|
||||
for i in range(index, len(nums) - 1):
|
||||
nums[i] = nums[i + 1]
|
||||
|
||||
|
||||
def traverse(nums: list[int]):
|
||||
"""배열 순회"""
|
||||
count = 0
|
||||
# 인덱스를 통해 배열을 순회한다
|
||||
for i in range(len(nums)):
|
||||
count += nums[i]
|
||||
# 배열의 원소를 직접 순회한다
|
||||
for num in nums:
|
||||
count += num
|
||||
# 데이터의 인덱스와 원소를 함께 순회한다
|
||||
for i, num in enumerate(nums):
|
||||
count += nums[i]
|
||||
count += num
|
||||
|
||||
|
||||
def find(nums: list[int], target: int) -> int:
|
||||
"""배열에서 지정한 원소 탐색"""
|
||||
for i in range(len(nums)):
|
||||
if nums[i] == target:
|
||||
return i
|
||||
return -1
|
||||
|
||||
|
||||
"""실행 코드"""
|
||||
if __name__ == "__main__":
|
||||
# 배열 초기화
|
||||
arr = [0] * 5
|
||||
print("배열 arr =", arr)
|
||||
nums = [1, 3, 2, 5, 4]
|
||||
print("배열 nums =", nums)
|
||||
|
||||
# 임의 접근
|
||||
random_num: int = random_access(nums)
|
||||
print("nums에서 무작위로 가져온 원소", random_num)
|
||||
|
||||
# 길이 확장
|
||||
nums: list[int] = extend(nums, 3)
|
||||
print("배열 길이를 8로 확장한 후 nums =", nums)
|
||||
|
||||
# 원소 삽입
|
||||
insert(nums, 6, 3)
|
||||
print("인덱스 3에 숫자 6을 삽입한 후 nums =", nums)
|
||||
|
||||
# 원소 삭제
|
||||
remove(nums, 2)
|
||||
print("인덱스 2의 원소를 삭제한 후 nums =", nums)
|
||||
|
||||
# 배열 순회
|
||||
traverse(nums)
|
||||
|
||||
# 원소 탐색
|
||||
index: int = find(nums, 3)
|
||||
print("nums에서 원소 3을 탐색하여 얻은 인덱스 =", index)
|
||||
@@ -0,0 +1,85 @@
|
||||
"""
|
||||
File: linked_list.py
|
||||
Created Time: 2022-11-25
|
||||
Author: krahets ([email protected])
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.append(str(Path(__file__).parent.parent))
|
||||
from modules import ListNode, print_linked_list
|
||||
|
||||
|
||||
def insert(n0: ListNode, P: ListNode):
|
||||
"""연결 리스트의 노드 n0 뒤에 노드 P 삽입"""
|
||||
n1 = n0.next
|
||||
P.next = n1
|
||||
n0.next = P
|
||||
|
||||
|
||||
def remove(n0: ListNode):
|
||||
"""연결 리스트의 노드 n0 바로 뒤에 있는 노드 삭제"""
|
||||
if not n0.next:
|
||||
return
|
||||
# n0 -> P -> n1
|
||||
P = n0.next
|
||||
n1 = P.next
|
||||
n0.next = n1
|
||||
|
||||
|
||||
def access(head: ListNode, index: int) -> ListNode | None:
|
||||
"""연결 리스트에서 인덱스가 index인 노드에 접근"""
|
||||
for _ in range(index):
|
||||
if not head:
|
||||
return None
|
||||
head = head.next
|
||||
return head
|
||||
|
||||
|
||||
def find(head: ListNode, target: int) -> int:
|
||||
"""연결 리스트에서 값이 target인 첫 번째 노드 탐색"""
|
||||
index = 0
|
||||
while head:
|
||||
if head.val == target:
|
||||
return index
|
||||
head = head.next
|
||||
index += 1
|
||||
return -1
|
||||
|
||||
|
||||
"""실행 코드"""
|
||||
if __name__ == "__main__":
|
||||
# 연결 리스트 초기화
|
||||
# 각 노드를 초기화한다
|
||||
n0 = ListNode(1)
|
||||
n1 = ListNode(3)
|
||||
n2 = ListNode(2)
|
||||
n3 = ListNode(5)
|
||||
n4 = ListNode(4)
|
||||
# 노드 사이의 참조를 설정한다
|
||||
n0.next = n1
|
||||
n1.next = n2
|
||||
n2.next = n3
|
||||
n3.next = n4
|
||||
print("초기화한 연결 리스트")
|
||||
print_linked_list(n0)
|
||||
|
||||
# 노드 삽입
|
||||
p = ListNode(0)
|
||||
insert(n0, p)
|
||||
print("노드를 삽입한 후의 연결 리스트")
|
||||
print_linked_list(n0)
|
||||
|
||||
# 노드 삭제
|
||||
remove(n0)
|
||||
print("노드를 삭제한 후의 연결 리스트")
|
||||
print_linked_list(n0)
|
||||
|
||||
# 노드 접근
|
||||
node: ListNode = access(n0, 3)
|
||||
print("연결 리스트에서 인덱스 3에 있는 노드의 값 = {}".format(node.val))
|
||||
|
||||
# 노드 탐색
|
||||
index: int = find(n0, 2)
|
||||
print("연결 리스트에서 값이 2인 노드의 인덱스 = {}".format(index))
|
||||
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
File: list.py
|
||||
Created Time: 2022-11-25
|
||||
Author: krahets ([email protected])
|
||||
"""
|
||||
|
||||
"""실행 코드"""
|
||||
if __name__ == "__main__":
|
||||
# 리스트 초기화
|
||||
nums: list[int] = [1, 3, 2, 5, 4]
|
||||
print("\n리스트 nums =", nums)
|
||||
|
||||
# 원소 접근
|
||||
x: int = nums[1]
|
||||
print("\n인덱스 1의 원소에 접근하여 얻은 x =", x)
|
||||
|
||||
# 원소 갱신
|
||||
nums[1] = 0
|
||||
print("\n인덱스 1의 원소를 0으로 갱신한 후 nums =", nums)
|
||||
|
||||
# 리스트 비우기
|
||||
nums.clear()
|
||||
print("\n리스트를 비운 후 nums =", nums)
|
||||
|
||||
# 맨 뒤에 원소 추가
|
||||
nums.append(1)
|
||||
nums.append(3)
|
||||
nums.append(2)
|
||||
nums.append(5)
|
||||
nums.append(4)
|
||||
print("\n원소를 추가한 후 nums =", nums)
|
||||
|
||||
# 중간에 원소 삽입
|
||||
nums.insert(3, 6)
|
||||
print("\n인덱스 3에 숫자 6을 삽입한 후 nums =", nums)
|
||||
|
||||
# 원소 삭제
|
||||
nums.pop(3)
|
||||
print("\n인덱스 3의 원소를 삭제한 후 nums =", nums)
|
||||
|
||||
# 인덱스를 통해 리스트를 순회한다
|
||||
count = 0
|
||||
for i in range(len(nums)):
|
||||
count += nums[i]
|
||||
# 리스트의 원소를 직접 순회한다
|
||||
for num in nums:
|
||||
count += num
|
||||
|
||||
# 두 리스트 연결
|
||||
nums1 = [6, 8, 7, 10, 9]
|
||||
nums += nums1
|
||||
print("\n리스트 nums1을 nums 뒤에 연결한 후 nums =", nums)
|
||||
|
||||
# 리스트 정렬
|
||||
nums.sort()
|
||||
print("\n리스트를 정렬한 후 nums =", nums)
|
||||
@@ -0,0 +1,118 @@
|
||||
"""
|
||||
File: my_list.py
|
||||
Created Time: 2022-11-25
|
||||
Author: krahets ([email protected])
|
||||
"""
|
||||
|
||||
|
||||
class MyList:
|
||||
"""리스트 클래스"""
|
||||
|
||||
def __init__(self):
|
||||
"""생성자"""
|
||||
self._capacity: int = 10 # 리스트 용량
|
||||
self._arr: list[int] = [0] * self._capacity # 배열(리스트 원소 저장)
|
||||
self._size: int = 0 # 리스트 길이(현재 원소 개수)
|
||||
self._extend_ratio: int = 2 # 리스트의 용량을 확장할 때마다 적용하는 배수
|
||||
|
||||
def size(self) -> int:
|
||||
"""리스트 길이(현재 원소 개수) 반환"""
|
||||
return self._size
|
||||
|
||||
def capacity(self) -> int:
|
||||
"""리스트 용량 반환"""
|
||||
return self._capacity
|
||||
|
||||
def get(self, index: int) -> int:
|
||||
"""원소 접근"""
|
||||
# 인덱스가 범위를 벗어나면 예외를 발생시킨다. 아래에서도 동일하다
|
||||
if index < 0 or index >= self._size:
|
||||
raise IndexError("인덱스가 범위를 벗어났다")
|
||||
return self._arr[index]
|
||||
|
||||
def set(self, num: int, index: int):
|
||||
"""원소 갱신"""
|
||||
if index < 0 or index >= self._size:
|
||||
raise IndexError("인덱스가 범위를 벗어났다")
|
||||
self._arr[index] = num
|
||||
|
||||
def add(self, num: int):
|
||||
"""맨 뒤에 원소 추가"""
|
||||
# 원소 개수가 용량을 초과하면 용량 확장을 수행한다
|
||||
if self.size() == self.capacity():
|
||||
self.extend_capacity()
|
||||
self._arr[self._size] = num
|
||||
self._size += 1
|
||||
|
||||
def insert(self, num: int, index: int):
|
||||
"""중간에 원소 삽입"""
|
||||
if index < 0 or index >= self._size:
|
||||
raise IndexError("인덱스가 범위를 벗어났다")
|
||||
# 원소 개수가 용량을 초과하면 용량 확장을 수행한다
|
||||
if self._size == self.capacity():
|
||||
self.extend_capacity()
|
||||
# 인덱스 index와 그 뒤의 원소를 모두 한 칸씩 뒤로 이동한다
|
||||
for j in range(self._size - 1, index - 1, -1):
|
||||
self._arr[j + 1] = self._arr[j]
|
||||
self._arr[index] = num
|
||||
# 원소 개수를 갱신한다
|
||||
self._size += 1
|
||||
|
||||
def remove(self, index: int) -> int:
|
||||
"""원소 삭제"""
|
||||
if index < 0 or index >= self._size:
|
||||
raise IndexError("인덱스가 범위를 벗어났다")
|
||||
num = self._arr[index]
|
||||
# 인덱스 index 뒤의 원소를 모두 한 칸씩 앞으로 이동한다
|
||||
for j in range(index, self._size - 1):
|
||||
self._arr[j] = self._arr[j + 1]
|
||||
# 원소 개수를 갱신한다
|
||||
self._size -= 1
|
||||
# 삭제한 원소를 반환한다
|
||||
return num
|
||||
|
||||
def extend_capacity(self):
|
||||
"""리스트 용량 확장"""
|
||||
# 원래 배열 길이의 _extend_ratio 배인 새 배열을 만들고 원래 배열을 새 배열에 복사한다
|
||||
self._arr = self._arr + [0] * self.capacity() * (self._extend_ratio - 1)
|
||||
# 리스트 용량을 갱신한다
|
||||
self._capacity = len(self._arr)
|
||||
|
||||
def to_array(self) -> list[int]:
|
||||
"""유효한 길이만큼의 리스트 반환"""
|
||||
return self._arr[: self._size]
|
||||
|
||||
|
||||
"""실행 코드"""
|
||||
if __name__ == "__main__":
|
||||
# 리스트 초기화
|
||||
nums = MyList()
|
||||
# 맨 뒤에 원소 추가
|
||||
nums.add(1)
|
||||
nums.add(3)
|
||||
nums.add(2)
|
||||
nums.add(5)
|
||||
nums.add(4)
|
||||
print(f"리스트 nums = {nums.to_array()}, 용량 = {nums.capacity()}, 길이 = {nums.size()}")
|
||||
|
||||
# 중간에 원소 삽입
|
||||
nums.insert(6, index=3)
|
||||
print("인덱스 3에 숫자 6을 삽입한 후 nums =", nums.to_array())
|
||||
|
||||
# 원소 삭제
|
||||
nums.remove(3)
|
||||
print("인덱스 3의 원소를 삭제한 후 nums =", nums.to_array())
|
||||
|
||||
# 원소 접근
|
||||
num = nums.get(1)
|
||||
print("인덱스 1의 원소에 접근하여 얻은 num =", num)
|
||||
|
||||
# 원소 갱신
|
||||
nums.set(0, 1)
|
||||
print("인덱스 1의 원소를 0으로 갱신한 후 nums =", nums.to_array())
|
||||
|
||||
# 용량 확장 동작 테스트
|
||||
for i in range(10):
|
||||
# i = 5일 때 리스트 길이가 용량을 초과하므로 용량 확장이 수행된다
|
||||
nums.add(i)
|
||||
print(f"용량을 확장한 리스트 {nums.to_array()}, 용량 = {nums.capacity()}, 길이 = {nums.size()}")
|
||||
Reference in New Issue
Block a user