Drop files here
or click to upload
import streamlit as st
import random
import time
import matplotlib.pyplot as plt
# 데이터 생성 함수
def generate_random_data(size, min_val, max_val):
return [random.randint(min_val, max_val) for _ in range(size)]
# 유효성 검사 함수
def validate_data(data):
if not data:
return False, "데이터가 비어 있습니다."
if not all(isinstance(x, int) for x in data):
return False, "모든 데이터는 정수여야 합니다."
if not all(-100 <= x <= 100 for x in data):
return False, "데이터는 -100 이상 100 이하이어야 합니다."
if len(data) < 2:
return False, "데이터가 너무 적습니다. 최소 2개 이상의 숫자가 필요합니다."
if len(data) > 100:
return False, "데이터가 너무 많습니다. 최대 100개까지만 지원합니다."
return True, ""
# Merge Sort with steps recording
# def merge_sort(arr):
# steps = []
# def _merge_sort(sub_arr):
# if len(sub_arr) > 1:
# mid = len(sub_arr) // 2
# left_half = sub_arr[:mid]
# right_half = sub_arr[mid:]
# _merge_sort(left_half)
# _merge_sort(right_half)
# i = j = k = 0
# while i < len(left_half) and j < len(right_half):
# if left_half[i] < right_half[j]:
# sub_arr[k] = left_half[i]
# i += 1
# else:
# sub_arr[k] = right_half[j]
# j += 1
# k += 1
# while i < len(left_half):
# sub_arr[k] = left_half[i]
# i += 1
# k += 1
# while j < len(right_half):
# sub_arr[k] = right_half[j]
# j += 1
# k += 1
# steps.append(sub_arr.copy())
# _merge_sort(arr.copy())
# return steps
# Merge Sort with steps recording - 수정된 버전
def merge_sort(arr):
steps = []
original_arr = arr.copy() # 전체 배열의 복사본 유지
def _merge_sort(sub_arr, start_idx, end_idx):
if len(sub_arr) > 1:
mid = len(sub_arr) // 2
left_half = sub_arr[:mid]
right_half = sub_arr[mid:]
_merge_sort(left_half, start_idx, start_idx + mid)
_merge_sort(right_half, start_idx + mid, end_idx)
i = j = k = 0
while i < len(left_half) and j < len(right_half):
if left_half[i] < right_half[j]:
sub_arr[k] = left_half[i]
original_arr[start_idx + k] = left_half[i] # 전체 배열 업데이트
i += 1
else:
sub_arr[k] = right_half[j]
original_arr[start_idx + k] = right_half[j] # 전체 배열 업데이트
j += 1
k += 1
while i < len(left_half):
sub_arr[k] = left_half[i]
original_arr[start_idx + k] = left_half[i] # 전체 배열 업데이트
i += 1
k += 1
while j < len(right_half):
sub_arr[k] = right_half[j]
original_arr[start_idx + k] = right_half[j] # 전체 배열 업데이트
j += 1
k += 1
# 의미있는 변경이 있을 때만 steps에 추가
if len(sub_arr) > 1:
steps.append(original_arr.copy())
_merge_sort(original_arr, 0, len(original_arr))
return steps
# Quick Sort with steps recording
def quick_sort(arr):
steps = []
def _quick_sort(sub_arr, low, high):
if low < high:
pi = partition(sub_arr, low, high)
steps.append(sub_arr.copy())
_quick_sort(sub_arr, low, pi - 1)
_quick_sort(sub_arr, pi + 1, high)
def partition(sub_arr, low, high):
pivot = sub_arr[high]
i = low - 1
for j in range(low, high):
if sub_arr[j] <= pivot:
i += 1
sub_arr[i], sub_arr[j] = sub_arr[j], sub_arr[i]
sub_arr[i + 1], sub_arr[high] = sub_arr[high], sub_arr[i + 1]
return i + 1
_quick_sort(arr.copy(), 0, len(arr) - 1)
return steps
# 정렬 과정 시각화 함수
# def visualize_steps(steps, title="Sorting Step"):
# for idx, step in enumerate(steps):
# st.subheader(f"{title} - Step {idx+1}")
# fig, ax = plt.subplots()
# ax.bar(range(len(step)), step, color='skyblue')
# ax.set_xlabel('Index')
# ax.set_ylabel('Value')
# ax.set_xticks(range(len(step))) # x축을 정수 인덱스로 고정
# plt.tight_layout()
# st.pyplot(fig)
# time.sleep(0.5)
def visualize_steps(steps, title="Sorting Step"):
for idx, step in enumerate(steps):
st.subheader(f"{title} - Step {idx+1}")
fig, ax = plt.subplots()
bars = ax.bar(range(len(step)), step, color='skyblue')
changed_indices = [] # <-- 항상 초기화
if idx > 0:
prev_step = steps[idx - 1]
changed_indices = [i for i in range(len(step)) if step[i] != prev_step[i]]
for ci in changed_indices:
bars[ci].set_color('orange') # 변경된 부분만 주황색 표시
ax.set_xlabel('Index')
ax.set_ylabel('Value')
ax.set_title(f"Step {idx+1}/{len(steps)}")
ax.set_xticks(range(len(step)))
plt.tight_layout()
st.pyplot(fig)
# 단계별 설명 추가
if changed_indices:
changed_values = [step[i] for i in changed_indices]
st.info(f"Changed indices: {changed_indices}, New values: {changed_values}")
else:
st.info("No data rearrangement in this step.")
time.sleep(0.5)
# Streamlit 메인 앱
def main():
st.title("고급 정렬 알고리즘 시각화")
st.write("Merge Sort와 Quick Sort의 과정을 단계별로 살펴보세요!")
option = st.radio("데이터 입력 방법을 선택하세요:", ("직접 입력", "랜덤 생성"))
data = None # <-- 초기화
if option == "직접 입력":
user_input = st.text_input("정수 리스트를 입력하세요 (예: 5,3,8,6):")
if user_input:
try:
data = list(map(int, user_input.split(',')))
except:
st.error("입력 형식이 잘못되었습니다. 쉼표로 구분된 정수를 입력하세요.")
else:
size = st.slider("데이터 크기 선택", 2, 100, 10)
min_val = st.number_input("최소값", value=-100)
max_val = st.number_input("최대값", value=100)
if min_val > max_val:
st.error("최소값은 최대값보다 작아야 합니다.")
return
data = generate_random_data(size, int(min_val), int(max_val))
st.write(f"랜덤 생성된 데이터: {data}")
# 데이터가 준비된 경우만 이후 코드 실행
if data is not None:
valid, msg = validate_data(data)
if not valid:
st.error(msg)
return
algo = st.selectbox("정렬 알고리즘 선택:", ("Merge Sort", "Quick Sort"))
if st.button("정렬 시작"):
st.write(f"초기 데이터: {data}")
if algo == "Merge Sort":
steps = merge_sort(data.copy())
visualize_steps(steps, title="Merge Sort")
else:
steps = quick_sort(data.copy())
visualize_steps(steps, title="Quick Sort")
if __name__ == "__main__":
main()
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?