19. 알고리즘5~7

wonny_·2023년 7월 28일
0

자료구조&알고리즘

목록 보기
8/10
  • 근삿값

    • 특정 값(참값)에 가장 가까운 값
[7, 43, 14, 44, 6, 26, 24, 3, 25, 47, 2, 32, 27, 38, 18, 17, 33, 29, 28, 0]

import random

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}')

Q. 근삿값 알고리즘을 이용해서 시험 점수를 입력하면 학점이 출력. 평균점수에 따른 학점 기준 점수는 다음과 같음

<near 파일>

def getNearNum(an):
    baseScores = [95, 85, 75, 65, 55]
    nearNum = 0
    minNum = 100

    for n in baseScores:
        absNums = abs(n - an)
        if absNums < minNum:
           minNum = absNums
           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 'E'
___________________________________      
   <실행문> 
   
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}')

  • 평균

    • 여러 수나 양의 중간값을 갖는 수
import random

nums = random.sample(range(0, 100), 10)
print(f'nums: {nums}')

total = 0
for n in nums:
    total += n

average = total / len(nums)
print(f'average: {round(average, 2)}')   

# 50 이상 90이하 수들의 평균

import random
nums = random.sample(range(0,100), 30)
print(f'nums: {nums}')

total = 0
targetNums = []
for n in nums:
    if n >= 50 and n <= 90:
       total += n
       targetNums.append(n)
average = total/len(targetNums)
print(f'total: {total}, average: {round(average, 2)}')

# 정수들의 평균

nums = [4, 5.12, 0, 5, 7.34, 9.1, 9, 3, 3.159, 1, 11, 12.789]
print(f'nums: {nums}')

targetNums = []
total = 0
for n in nums:
    if n - int(n) == 0: # 실수들의 평균: if n - int(n) != 0
       total += n
      targetNums.append(n)
    
print(f'nums: {targetNums}')
average = total/ len(targetNums)

print(f'total: {targetNums}, average: {round(average, 2)}')

<near 모듈>

class Top5Players:

    def __init__(self, cs, ns):
        self.currentScores = cs
        self.newScores = ns

    def setAlignScore(self):

        nearIdx = 0
        nearScore = 0
        minNum = 10.0 

        for i, s in enumerate(self.currentScores):
            absNum = abs(self.newScores - s)

            if absNum < minNum:
               inNum = absNum
               nearIdx = i
               nearScore = s

        if self.newScores >= self.currentScores[nearIdx]:
           for i in range(len(self.currentScores)-1, nearIdx, -1):
               self.currentScores[i] = self.currentScores[i-1]

           self.currentScores[nearIdx] = self.newScores

       else:
           for i in range(len(self.currentScores)-1, nearIdx+1, -1):
               self.currentScores[i] = self.currentScores[i-1]

           self.currentScores[nearIdx] = self.newScores

    def getFinalTop5Scores(self):
        return self.currentScores

_________________________________________________________________

<실행문> 

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'top5PlayerScores: {top5PlayerScores}')

total = 0; average = 0
for n in scores:
    total += n

average = round(total/ len(scores), 2)
print(f'total: {total}, average: {average}')

tp = near.Top5Players(top5PlayerScores, average)
tp.setAlignScore()
top5PlayerScores = tp.getFinalTop5Scores()
print(f'top5PlayerScores = {top5PlayerScores}')

  • 재귀

    • 나 자신을 다시 호출하는 것
# 반복문 대신 재귀함수 

def recusion(num):

    if num > 0:
        print('*' * num)
        return recusion(num-1)
    else:
        return 1

recusion(10)

# 재귀함수 이용한 팩토리얼

def factorial(num):

if num > 0:
    return num * factorial(num-1) #num이 1일 때까지 곱하여 팩토리얼형태
else:
    return 1

print(f'factorial(10): {factorial(10)}')

Q. 재귀 알고리즘 이용한 최대공약수 

def gcd(n1, n2):

    if n1 % n2 == 0:
        return n2
    else:
        return gcd(n2, n1 % n2)

print(f'gcd(82, 32): {gcd(82, 32)}')
print(f'gcd(96, 40): {gcd(96, 40)}')
_____________________________________

# 반복문 이용한 최대공약수 

def gcd(n1, n2):

    maxNum = 0
    for i in range(1, (n1+1)):
        if n1 % i == 0 and n2 % i == 0: #공약수 구하기
            maxNum = i

    return maxNum
print(f'gcd(82, 32): {gcd(82, 32)}')
print(f'gcd(96, 40): {gcd(96, 40)}')

  • 하노이 탑

    • 퍼즐게임의 일종으로 세 개의 기둥을 이용해서 원판을 다른 기둥으로 옮기면 되고 제약 조건은 다음과 같음
      • 한 번에 한개의 원판만 옮길 수 있다.
      • 큰 원판이 작은 원판 위에 있어서는 안 된다.
def moveDisc(discCnt, fromBar, toBar, viaBar): # 원판개수, 출발기둥, 도착기둥, 경유기둥

    if discCnt == 1:
          print(f'{discCnt}disc를 {fromBar}에서 {toBar}로 이동')

    else: #discCnt-1개들을 경유 기둥으로 이동
        moveDisc(discCnt-1, fromBar, viaBar, toBar)

        #discCnt를 목적 기둥으로 이동
        print(f'{discCnt}disc를 {fromBar}에서 {toBar}로 이동')

        #discCnt-1개들을 도착 기둥으로 이동
        moveDisc(discCnt-1, viaBar, toBar, fromBar)

moveDisc(3, 1, 2, 3)

  • 병합정렬

    • 자료구조를 분할하고 각각의 분할된 자료구조를 정렬한 후 다시 병합하여 정렬
def mSort(ns):

    if len(ns) < 2:
       return ns

    midIdx = len(ns) // 2 
    leftNums = mSort(ns[0:midIdx]) 
    rightNums = mSort(ns[midIdx:len(ns)]) 
    
    mergeNums = []
    leftIdx = 0; rightIdx = 0
    
    while leftIdx < len(leftNums) and rightIdx < len(rightNums):

        if leftNums[leftIdx] < rightNums[rightIdx]:
           mergeNums.append(leftNums[leftIdx])
           leftIdx += 1

        else:
            mergeNums.append(rightNums[rightIdx])
            rightIdx += 1

    mergeNums = mergeNums + leftNums[leftIdx:]
    mergeNums = mergeNums + rightNums[rightIdx:]

    return mergeNums

nums = [8, 1, 4, 3, 2, 5, 10, 6]
print(f'mSort(nums): {mSort(nums)}')

Q. 1-100까지 난수 10개를 생성하고 다음의 요구사항을 만족하는 모듈 
요구1) 병합정렬 알고리즘을 이용한 난수 정렬 모듈 구현
요구2) 위의 모듈에 오름차순과 내림차순을 선택할 수 있는 옵션 추가 

<sortMod 모듈>

def mSort(ns, asc=True): 

    if len(ns) < 2:
       return ns

    midIdx = len(ns) //2
    leftNums = mSort(ns[0:midIdx], asc=asc)
    rightNums = mSort(ns[midIdx:len(ns)], asc=asc)

    mergeNums = []
    leftIdx = 0; rightIdx = 0
    while leftIdx < len(leftNums) and rightIdx < len(rightNums):

    if asc:
        if leftNums[leftIdx] < rightNums[rightIdx]:
            mergeNums.append(leftNums[leftIdx])
            leftIdx += 1

        else:
            mergeNums.append(rightNums[rightIdx])
            rightIdx += 1
    else:
        if leftNums(leftIdx) > rightNums[rightIdx]:
            mergeNums.append(leftNums[leftIdx])
            leftIdx += 1

        else:
            mergeNums.append(rightNums[rightIdx])
            rightIdx += 1

   mergeNums = mergeNums + leftNums[leftIdx:]
   mergeNums = mergeNums + rightNums[rightIdx:]
   return mergeNums
  _______________________________________________________
  
<실행문>
  
import random as rd
import sortMod as sm

rNums = rd.sample(range(1, 101), 10)
print(f'not sorted rNums: {rNums}')
print(f'sorted rNums: {sm.mSort(rNums)}')
print(f'sorted rNums ASC: {sm.mSort(rNums)}')
print(f'sorted rNums DESC: {sm.mSort(rNums, asc=False)}')

  • 퀵정렬

    • 기준 값 보다 작은 값으로 분리한 후 다시 합침
def qSort(ns):

    if len(ns) < 2:
        return  ns

    midIdx = len(ns) // 2
    midVal = ns[midIdx]

    smallNums = []; sameNums = []; bigNums = [] #왼쪽 중앙 오른쪽

    for n in ns:
        if n < midVal:
           smallNums.append(n)
        elif n == midVal:
            sameNums.append(n)
        else:
            bigNums.append(n)
    return qSort(smallNums) + sameNums + qSort(bigNums)

nums = [8, 1, 4, 3, 2, 5, 4, 10, 6, 8]
print(f'qSort(nums): qSort{nums}')

Q. 1-100 난수 10개 생성하고 다음 요구사항 만족하는 모듈
요구1) 퀵정렬 알고리즘 이용한 난수 정렬 모듈 구현
요구2) 위의 모듈에 오름차순과 내림차순 선택할 수 있는 옵션 추가 

<sortMod 모듈>

def qSort(ns, asc=True):

    if len(ns) < 2:
        return  ns

    midIdx = len(ns) // 2
    midVal = ns[midIdx]

    smallNums = []; sameNums = []; bigNums = []

    for n in ns:

        if n < midVal:
           sameNums.append(n)
        elif n == midVal:
            sameNums.append(n)
        else:
            bigNums.append(n)

    if asc:
        return qSort(smallNums, asc=asc) + sameNums + qSort(bigNums, asc=asc)
    else:
       return qSort(bigNums, asc=asc) + sameNums + qSort(smallNums, asc=asc)
_____________________________________________________________________________
<실행문> 

import random as rd
import sortMod as sm

rNums = rd.sample(range(1, 100), 10)
print(f'not sorted rNums: {rNums}')
print(f'sorted rNums ASC: {sm.qSort(rNums)}')
print(f'sorted rNums DESC: {sm.qSort(rNums, asc=False)}')

profile
파이팅

0개의 댓글