[강의 요약]
[Part 03. 자료구조&알고리즘 with Python_ Ch 03. 알고리즘] 강의 수강
13_최댓값부터 22_평균(실습)까지 강의 수강하였음
🐢 100일 챌린지 🔥 : [▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰░ ] 47/100일 (47%)
[13_최댓값]
▶ 최댓값 개념
여러 개의 수 중에서 가장 큰 수
예시를 통해 이해해 보자.
[-2, -4, 5, 7, 10, 0, 8, 20, -11]
처음 값(-2)을 기준으로 삼고
나머지 값들과 하나씩 비교하면서 더 큰 값이 나오면 maxNum을 교체
끝까지 비교한 후 남은 maxNum이 최댓값임
▶ 코드 : 최댓값 클래스 구현
class MaxAlgorithm:
def __init__(self, ns):
self.nums = ns
self.maxNum = 0
def getMaxNum(self):
self.maxNum = self.nums[0] # 첫 번째 값을 초기 최대값으로 설정
for n in self.nums:
if self.maxNum < n: # 더 큰 값이 있으면 교체
self.maxNum = n
return self.maxNum
# 실행
ma = MaxAlgorithm([-2, -4, 5, 7, 10, 0, 8, 20, -11])
maxNum = ma.getMaxNum()
print(f'maxNum: {maxNum}')
[출력 결과]
maxNum: 20
[14_최댓값(실습)]
▶ 접근 방법
알파벳 문자 중에서 아스키코드 값이 가장 큰 문자를 찾아야 한다면
['c', 'x', 'Q', 'A', 'e', 'P', 'p']
각 문자의 ord() 값으로 비교
가장 큰 아스키코드를 가진 문자가 최댓값이 된다.
▶ 실습 코드 : 리스트에서 아스키코드가 가장 큰 값을 찾는 알고리즘 만들기
class MaxAlgorithm:
def __init__(self, cs):
self.chars = cs
self.maxChar = 0
def getMaxChar(self):
self.maxChar = self.chars[0] # 첫 문자를 초기 최댓값으로 설정
for c in self.chars:
if ord(self.maxChar) < ord(c): # 아스키코드 기준으로 비교
self.maxChar = c
return self.maxChar
# 실행
ma = MaxAlgorithm(['c', 'x', 'Q', 'A', 'e', 'P', 'p'])
maxChar = ma.getMaxChar()
print(f'maxChar: {maxChar}')
문자 → 숫자 변환을 통해 기존 알고리즘 재활용 가능
[출력 결과]
maxChar: x
'x'는 아스키코드 120으로 가장 크다.
[15_최솟값]
▶ 최솟값 개념
최솟값은 자료 구조 안에서 가장 작은 수
리스트에서 최솟값을 찾는 기본 원리는 다음과 같음
리스트의 첫 값을 기준 최솟값으로 설정
이후 나머지 값을 하나씩 순회하며
더 작은 값이 나타나면 갱신
리스트 끝까지 비교를 마치면 최솟값 도출
▶ 코드 : 자료구조에서 가장 작은 값을 찾는다
class MinAlgorithm:
def __init__(self, ns):
self.nums = ns
self.minNum = 0
def getMinNum(self):
self.minNum = self.nums[0]
for n in self.nums:
if self.minNum > n:
self.minNum = n
return self.minNum
# 실행
ma = MinAlgorithm([-2, -4, 5, 7, 10, 0, 8, 20, -11])
minNum = ma.getMinNum()
print(f'minNum: {minNum}')
[출력 결과]
minNum: -11
[16_최솟값(실습)]
▶ 접근 방법
알파벳 문자 중에서 아스키코드 값이 가장 작은 문자를 찾아야 한다면
['c', 'x', 'Q', 'A', 'e', 'P', 'p']
각 문자의 ord() 값을 비교
가장 작은 아스키코드를 가진 문자가 최솟값임
▶ 실습 코드 : 리스트에서 아스키코드가 가장 작은 값을 찾는 알고리즘 만들기
class MinAlgorithm:
def __init__(self, cs):
self.chars = cs
self.minChar = 0
def getMinChar(self):
self.minChar = self.chars[0]
for c in self.chars:
if ord(self.minChar) > ord(c):
self.minChar = c
return self.minChar
# 실행
ma = MinAlgorithm(['c', 'x', 'Q', 'A', 'e', 'P', 'p'])
minChar = ma.getMinChar()
print(f'minChar: {minChar}')
[출력 결과]
minChar: A
'A'는 아스키코드 65로, 리스트 내에서 가장 작은 문자임
[17_최빈값]
▶ 최빈값 개념
최빈값은 데이터셋에서 가장 자주 등장하는 값
nums = [1, 3, 7, 6, 7, 7, 7, 12, 12, 17]
7이 총 4번 등장하여 최빈값
12는 2번, 나머지는 1번 이하 등장
▶ 코드 : 최빈값 구현
class MaxAlgorithm:
def __init__(self, ns):
self.nums = ns
self.maxNum = 0
self.maxNumIdx = 0
def setMaxIdxAndNum(self):
self.maxNum = self.nums[0]
self.maxNumIdx = 0
for i, n in enumerate(self.nums):
if self.maxNum < n:
self.maxNum = n
self.maxNumIdx = i
def getMaxNum(self):
return self.maxNum
def getMaxNumIdx(self):
return self.maxNumIdx
# 원본 데이터
nums = [1, 3, 7, 6, 7, 7, 7, 12, 12, 17]
# 가장 큰 수를 기준으로 빈도 리스트 크기 결정
maxAlo = MaxAlgorithm(nums)
maxAlo.setMaxIdxAndNum()
maxNum = maxAlo.getMaxNum()
# 빈도 리스트 생성
indexes = [0 for _ in range(maxNum + 1)]
# 등장 횟수 기록
for n in nums:
indexes[n] += 1
# 가장 많이 등장한 횟수와 그 인덱스(=값)를 찾음
maxAlo = MaxAlgorithm(indexes)
maxAlo.setMaxIdxAndNum()
maxNum = maxAlo.getMaxNum()
maxNumIdx = maxAlo.getMaxNumIdx()
print(f'즉, {maxNumIdx}의 빈도수가 {maxNum}로 가장 높다.')
indexes 리스트를 만들어서 등장 횟수 누적
MaxAlgorihm을 통해 최댓값 알고리즘 재활용
[출력 결과]
즉, 7의 빈도수가 4로 가장 높다.
[18_최빈값(실습)]
▶ 실습 문제
▶ maxScore.py : 최댓값 알고리즘 모듈
class MaxAlgorithm:
def __init__(self, ns):
self.nums = ns
self.maxNum = 0
self.maxNumIdx = 0
def setMaxIdxAndNum(self):
self.maxNum = self.nums[0]
self.maxNumIdx = 0
for i, n in enumerate(self.nums):
if self.maxNum < n:
self.maxNum = n
self.maxNumIdx = i
def getMaxNum(self):
return self.maxNum
def getMaxNumIdx(self):
return self.maxNumIdx
▶ modeEx.py : 실습 메인 코드
import random
import maxScore as ms
# 점수 100명 생성 (70~100 사이 5점 단위)
scores = []
for i in range(100):
rn = random.randint(71, 100)
if rn != 100:
rn = rn - (rn % 5)
scores.append(rn)
# 최댓값(최고 점수)을 기준으로 인덱스 리스트 크기 생성
maxAlo = ms.MaxAlgorithm(scores)
maxAlo.setMaxIdxAndNum()
maxNum = maxAlo.getMaxNum()
# 각 점수별 빈도수 기록 리스트
indexes = [0 for i in range(maxNum + 1)]
for n in scores:
indexes[n] += 1
# 가장 높은 빈도수부터 하나씩 출력 (중복 피하기 위해 사용 후 0으로 초기화)
n = 1
while True:
maxAlo = ms.MaxAlgorithm(indexes)
maxAlo.setMaxIdxAndNum()
maxNum = maxAlo.getMaxNum()
maxNumIdx = maxAlo.getMaxNumIdx()
if maxNum == 0:
break
print(f'{n}. {maxNumIdx}빈도수: {maxNum}\t', end='')
print('+' * maxNum)
indexes[maxNumIdx] = 0 # 출력한 값은 다시 선택되지 않도록 초기화
n += 1
점수별 등장 횟수를 기록 → 최댓값 알고리즘으로 최빈값 출력
[출력 결과]
1. 80빈도수: 19 +++++++++++++++++++
2. 90빈도수: 17 +++++++++++++++++
3. 75빈도수: 16 ++++++++++++++++
...
+ 막대가 길수록 해당 점수를 받은 학생이 많다는 의미
[19_근삿값]
▶ 근삿값 개념
근삿값은 어떤 기준값과 가장 가까운 값
기준값과 리스트의 각 값을 뺀 후 abs()로 차이를 계산
그중 가장 차이가 작은 값이 근삿값
nums = [7, 43, 14, 44, 6, 26, ...]
inputNum = 11
→ abs(7 - 11) = 4
→ abs(14 - 11) = 3
→ abs(6 - 11) = 5
→ ...
→ 가장 차이가 작은 값: 14 → 근삿값
▶ 코드
import random
# 0~49 사이 중복 없는 20개 숫자 생성
nums = random.sample(range(0, 50), 20)
print(f'nums: {nums}')
# 사용자 입력값
inputNum = int(input('input number: '))
print(f'inputNum: {inputNum}')
# 초기값 설정
nearNum = 0
minNum = 50 # 차이의 최소값 (초기에는 최대값으로 설정)
# 반복문으로 절대값 차이 계산
for n in nums:
absNum = abs(n - inputNum)
if absNum < minNum: # 최솟값 갱신
minNum = absNum
nearNum = n
# 결과 출력
print(f'nearNum: {nearNum}')
[출력 결과]
nums: [7, 43, 14, 44, 6, 26, 24, 3, 25, 47, 2, 32, 27, 38, 18, 17, 33, 29, 28, 0]
input number: 11
nearNum: 14
[20_근삿값(실습)]
▶ 실습 문제
▶ near.py : 근삿값 기반 학점 판별 함수
def getNearNum(an):
baseScore = [95, 85, 75, 65, 55]
nearNum = 0
minNum = 100
for n in baseScore:
absNum = abs(n - an)
if absNum < minNum:
minNum = absNum
nearNum = n
if nearNum == 95:
return 'A'
elif nearNum == 85:
return 'B'
elif nearNum == 75:
return 'C'
elif nearNum == 65:
return 'D'
elif nearNum <= 55:
return 'F'
▶ nearEx.py : 실습 실행 파일
import near
scores = []
kor = int(input('input kor score: '))
scores.append(kor)
eng = int(input('input eng score: '))
scores.append(eng)
mat = int(input('input mat score: '))
scores.append(mat)
sci = int(input('input sci score: '))
scores.append(sci)
his = int(input('input his score: '))
scores.append(his)
totalScore = sum(scores)
print(f'totalScore: {totalScore}')
avgScore = totalScore / len(scores)
print(f'avgScore: {avgScore}')
grade = near.getNearNum(avgScore)
print(f'grade: {grade}')
[출력 결과]
input kor score: 90
input eng score: 80
input mat score: 85
input sci score: 90
input his score: 85
totalScore: 430
avgScore: 86.0
grade: B
[21_평균]
▶ 평균 개념
여러 수나 양의 중간값을 갖는 수를 평균이라 함
▶ 코드 : 전체 리스트 평균 구하기
import random
nums = random.sample(range(0, 100), 30)
print(f'nums: {nums}')
total = 0
for n in nums:
total += n
average = total / len(nums)
print(f'average: {round(average, 2)}')
[출력 결과]
nums: [88, 3, 2, 89, 59, 27, 20, 48, 17, 63, 35, 6, 73, 4, 71, 67, 22, 30, 60, 43, 50, 76, 42, 25, 18, 8, 14, 0, 5, 80]
average: 40.7
▶ 코드 : 50 이상 90 이하 평균
nums = random.sample(range(0, 100), 30)
targetNums = []
total = 0
for n in nums:
if 50 <= n <= 90:
total += n
targetNums.append(n)
print(f'targetNums: {targetNums}')
average = total / len(targetNums)
print(f'average: {round(average, 2)}')
[출력 결과]
targetNums: [89, 59, 63, 73, 71, 67, 60, 50, 76, 80]
average: 68.8
▶ 코드 : 정수만 골라 평균 구하기
nums = [4, 5.12, 0, 5, 7.34, 9.1, 9, 3, 3.159, 1, 11, 12.789]
targetNums = []
total = 0
for n in nums:
if n - int(n) == 0:
total += n
targetNums.append(n)
print(f'targetNums: {targetNums}')
average = total / len(targetNums)
print(f'average: {round(average, 2)}')
[출력 결과]
targetNums: [4, 0, 5, 9, 3, 1, 11]
average: 4.71
▶ 코드 : 소수(실수)만 골라 평균 구하기
nums = [4, 5.12, 0, 5, 7.34, 9.1, 9, 3, 3.159, 1, 11, 12.789]
targetNums = []
total = 0
for n in nums:
if n - int(n) != 0:
total += n
targetNums.append(n)
print(f'targetNums: {targetNums}')
average = total / len(targetNums)
print(f'average: {round(average, 2)}')
[출력 결과]
targetNums: [5.12, 7.34, 9.1, 3.159, 12.789]
average: 7.9
[22_평균(실습)]
▶ 실습 문제
▶ averageEx.py : 메인 로직
import near
scores = (8.9, 7.6, 8.2, 9.1, 8.8, 8.1, 7.9, 9.4, 7.2, 8.7)
top5PlayerScores = [9.12, 8.95, 8.12, 7.90, 7.88]
print(f'Current scores: {top5PlayerScores}')
total = 0
for n in scores:
total += n
average = round(total / len(scores), 2)
print(f'total: {total}')
print(f'average: {average}')
tp = near.Top5Players(top5PlayerScores, average)
tp.setAlignScore()
top5PlayerScores = tp.getFinalTop5Scores()
print(f'Final scores: {top5PlayerScores}')
▶ near.py : Top5 Players 클래스
class Top5Players:
def __init__(self, cs, ns):
self.currentScores = cs
self.newScore = ns
def setAlignScore(self):
nearIdx = 0
nearScore = 0
minNum = 10.0
for i, s in enumerate(self.currentScores):
absNum = abs(self.newScore - s)
if absNum < minNum:
minNum = absNum
nearIdx = i
nearScore = s
if self.newScore >= self.currentScores[nearIdx]:
for i in range(len(self.currentScores)-1, nearIdx, -1):
self.currentScores[i] = self.currentScores[i-1]
self.currentScores[nearIdx] = self.newScore
else:
for i in range(len(self.currentScores)-1, nearIdx+1, -1):
self.currentScores[i] = self.currentScores[i-1]
self.currentScores[nearIdx+1] = self.newScore
def getFinalTop5Scores(self):
return self.currentScores
[출력 결과]
Current scores: [9.12, 8.95, 8.12, 7.9, 7.88]
total: 83.9
average: 8.39
Final scores: [9.12, 8.95, 8.39, 8.12, 7.9]
평균 8.39는 기존 점수 중 8.12와 가장 가까우므로 그 앞에 삽임 됨
[나의 생각 정리]
다양한 리스트 기반 알고리즘을 정리했다.
반복문과 조건문만으로 평균, 최빈값, 최댓값 등의 기능들을 구현할 수 있었다.
클래스와 함수로 기능을 분리하면서 코드도 재사용할 수 있었다.
[적용점]
데이터 분석할 때 데이터 정제, 이상치 탐색, 분포 확인에 오늘 정리한 로직들을 응용할 수 있을 것 같다.
근삿값과 최빈값 같은 알고리즘은 추천 시스템이나 점수 보정 등에 활용 가능할 것 같다.
조건에 따른 필터링 후 계산하면 문제 해결 과정이 간단해질 것 같다.
“이 글은 제로베이스 데이터 스쿨 주 3일반 강의 자료 일부를 발췌하여 작성되었습니다.”
'제로베이스 데이터 취업 파트타임 > 100일 챌린지_일일 학습 일지' 카테고리의 다른 글
제로베이스 데이터 파트타임 스쿨 학습 일지 [25.05.04] (2) | 2025.05.04 |
---|---|
제로베이스 데이터 파트타임 스쿨 학습 일지 [25.05.03] (0) | 2025.05.03 |
제로베이스 데이터 파트타임 스쿨 학습 일지 [25.05.01] (1) | 2025.05.01 |
제로베이스 데이터 파트타임 스쿨 학습 일지 [25.04.30] (0) | 2025.04.30 |
제로베이스 데이터 파트타임 스쿨 학습 일지 [25.04.29] (1) | 2025.04.29 |