기본 제어 구조

Suhyeon Lee·2024년 10월 14일
0

조건문(if/else)

  • 특정 조건일 때 아래 내용을 실행
  • 프로그래밍을 하다 보면 여러 가지 상황에 대한 분기를 나누어서 처리해야 하는 경우가 생기는데, 이때 조건문을 사용
# if문의 기본구조

if 조건문:
    수행할 문장
else:
    수행할 문장
  • 조건문을 확인해 참이면 if 바로 아래 문장을 수행하고 거짓이면 eles 아래 문장을 수행

예시

# Pseudocode(슈도코드; 의사코드)
# 특정 프로그래밍 언어의 문법이 아니라 사람의 언어로 코드를 흉내 내 알고리즘 표현
# 프로그램을 작성할 때 각 모듈이 작동하는 논리를 표현하기 위한 언어
if 밖에 나갈때:
    
    if 날씨가 춥다면:
        롱 패딩을 입고 나간다.
    
    if 날씨가 덥다면:
        반팔을 입고나간다.
else:
	아무일도 하지 않음
    
# 위 의사코드를 코드로 작성 
out = True

temp = "춥다"

if out:
    if temp == "춥다":
        print("롱 패딩을 입고 나간다.")
    if temp == "덥다":
        print("반팔을 입고나간다.")
else:
		pass

# + 조건문이 참일때 그냥 아무일도 하지않고 넘어감
if out:
    pass
else:
    print(" ")

추가: elif

  • if else 만으로는 다양한 조건을 판단하기 어려울 때 elif를 사용하여 분기를 더욱 깔끔하게 나눌 수 있음
hour = 8

if hour == 8:
    print("기상")
elif hour == 12:
    print("점심")
elif hour == 18:
    print("저녁")

조건문에서 사용되는 비교연산자

  • 비교연산자: <, >, ==(같다), !=(같지 않다), >=, <=
  • or: 둘 중 하나만 참이어도 참
  • and: 모두 참이어야 참
  • not: 거짓이면 참
  • in, not in

while, for loop 반복문

while 조건문:
	수행할 문장
    
# 예시
open = 0

while open < 10:
    open += 1
    print(f"{open}번 상자를 열었습니다.")
    if open == 10:
        print("모든 상자를 열었습니다.")
  • 위 문장은 open이 10보다 작으면 계속 반복됨
  • 아래 수행하는 문장을 보면 open에 값을 계속 1씩 증가시키고 open 10이 되면 모든 상자를 열었다는 문장을 출력 후 open이 10이 되어 open이 10보다 작다는 조건이 False가 되고 while문에서 빠져나가게 됨
# break를 이용한 탈출
box = 10

while True:
    print("상자를 구매합니다")
    box -= 1
    if not box:
        print("상자가 0개라 더 이상 구매할 수 없습니다.")
        break

# continue를 이용한 홀수만 출력
num = 0

while num < 10:
    num += 1
    if num % 2 == 0:
        continue
    print(num)
  • break: while문을 강제로 빠져나가고 싶을 때
  • continue: while문을 빠져 나가지 않고 맨 처음 조건문으로 돌아가고 싶을 때

Mission2

프로그래머스 코딩테스트: 모의고사

def solution(answers):  
    pattern_1 = [1, 2, 3, 4, 5]
    pattern_2 = [2, 1, 2, 3, 2, 4, 2, 5]
    pattern_3 = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]
    score = [0, 0, 0]
    result = []
    
    for idx, answer in enumerate(answers):
        if answer == pattern_1[idx%len(pattern_1)]:
            score[0] += 1
        if answer == pattern_2[idx%len(pattern_2)]:
            score[1] += 1
        if answer == pattern_3[idx%len(pattern_3)]:
            score[2] += 1

    for idx, s in enumerate(score):
        if s == max(score):
            result.append(idx+1)
    
    return result
  • line 9 에서 pattern1[idx%len(pattern_1)] 하는 이유
    • pattern마다 순환주기가 다르기 때문 (각각 순환주기로 나눠준 것)
    • answers의 길이와 패턴 1,2,3의 각각의 길이는 다르지만, 패턴 1,2,3의 요소를 계속 반복적으로 사용하여 길이를 맞추어 사용할 수 있게 등록
    • idx%len(pattern_1): 나머지 연산을 이용
      • 어떤 수를 x로 나누면 결과는 무조건 x보다 작습니다.
      • 그래서 특정 범위 내 숫자를 구할 때 자주 사용합니다.
  • line 18에서 idx + 1 하는 이유
    • 리스트 내에서의 index는 0,1,2 인데 반해 수포자 이름은 1,2,3이기 때문
  • idx%len(pattern_1)로 매번 모듈러 연산을 하는것 보다는 if idx >= len(pattern_1): idx = 0과 같이 하게 되면 좀 더 효율이 올라간다고 함
  • enumerate
    • 반복문 사용 시 몇 번째 반복문인지 확인이 필요할 때 사용
    • 인덱스 번호와 컬렉션의 원소를 tuple형태로 반환합니다.
  • 매번 반복문에 max를 넣으면 효율성 이슈가 있으니 조심해야 함

다른 풀이

def solution(answers):
    p = [[1, 2, 3, 4, 5],
         [2, 1, 2, 3, 2, 4, 2, 5],
         [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]]
    s = [0] * len(p)

    for q, a in enumerate(answers):
        for i, v in enumerate(p):
            if a == v[q % len(v)]:
                s[i] += 1
    return [i + 1 for i, v in enumerate(s) if v == max(s)]
  • q가 0 1 2 3 4 이렇게 증가하는 인덱스이면... 두번째 루프에서 v가 각각 리스트의 길이인 5,6,7이 되기 때문에... 5,6,7 마다 cycle이 도는 원리를 이용
  • 첫 번째 반복문에서 enumerate를 썻으니 q=0 일때; a는 anwers의 첫번째 값입니다 그걸 데리고 가서 두번째 반복문에서 i=0 일때; v는 p의 첫번째값 즉, [1,2,3,4,5]가 됩니다. if 절에서 a의 값은 answers의 첫 번째입니다. v[q% len(v)]는 v중에서 q%len(v) 번째를 나타냅니다. 여기선, v[0나누기5의나머지] 니까 v[0] 입니다. ([1,2,3,4,5] 에서 0번째에 해당)
from itertools import cycle

def solution(answers):
    giveups = [
        cycle([1,2,3,4,5]),
        cycle([2,1,2,3,2,4,2,5]),
        cycle([3,3,1,1,2,2,4,4,5,5]),
    ]
    scores = [0, 0, 0]
    for num in answers:
        for i in range(3):
            if next(giveups[i]) == num:
                scores[i] += 1
    highest = max(scores)

    return [i + 1 for i, v in enumerate(scores) if v == highest]
  • 패턴을 generator로써 처리하여 공간복잡도까지 고려가 된 코드
def answer_type(pattern, length):
    return pattern * (length // len(pattern)) + pattern[:length%len(pattern)]

def check_answer(p, a):
    return [(x==y) for x,y in zip(p,a)].count(True)

def solution(answers):
    p1 = [1,2,3,4,5]
    p2 = [2,1,2,3,2,4,2,5]
    p3 = [3,3,1,1,2,2,4,4,5,5]
    ps = [p1,p2,p3]
    anws =  [answer_type(p, len(answers)) for p in ps]
    chks = [check_answer(a, answers) for a in anws]
    return [i+1 for i in range(len(ps)) if chks[i] == max(chks)]
a = [1, 2, 3, 4, 5]
b = [2, 1, 2, 3, 2, 4, 2, 5]
c = [3, 3, 1, 1, 2, 2, 4, 4, 5, 5]



def solution(answers):
    answer = []
    aa = [1 for i, val in enumerate(answers) if a[i % 5] == val]
    bb = [1 for i, val in enumerate(answers) if b[i % 8] == val]
    cc = [1 for i, val in enumerate(answers) if c[i % 10] == val]

    x = max([len(aa),len(bb),len(cc)])

    if x == len(aa) :
        answer.append(1)
    if x == len(bb) :
        answer.append(2)
    if x == len(cc) :
        answer.append(3)

    sorted(answer)

    return answer
from itertools import cycle
import numpy as np
def solution(answers):
    p1 = [1,2,3,4,5]
    p2 = [2,1,2,3,2,4,2,5]
    p3 = [3,3,1,1,2,2,4,4,5,5]
    seq = zip(cycle(p1), cycle(p2), cycle(p3))
    res = np.zeros(3)
    for sol in answers:
        tmp = np.array(next(seq))
        res[tmp==sol] += 1

    cnt = np.count_nonzero(res[res==res.max()])
    if not cnt:
        return []

    res = res.argsort()+1
    return list(res[3-cnt:])

코드를 구성하는 것에는 왕도가 없지만 원하는 기능과 향후 확장성 등을 생각해 문제를 풀어 나가는 것이 중요하다!

profile
2 B R 0 2 B

0개의 댓글