20260411 오늘의 학습: 약점 집중 연습

Yesol Lee·2026년 4월 11일

COS Python

목록 보기
16/30

지난 학습 요약

  • 구름EDU 기출 3회차 전체 완료 (10문제 모두 최종 정답)
  • 슬라이딩 윈도우, 문자열 순환 처리(text*2) 새로 학습
  • 내장함수명 변수 사용, 하드코딩 습관 재발 → 지속 주의 필요

오늘 수업 계획

  • 14차에서 발견된 취약 영역 3가지를 집중 복습
  • 슬라이딩 윈도우 → 문자열 순환 → 함수 작성 종합 순서로 총 6문제

학습 내용 정리

1. 슬라이딩 윈도우 — 빈칸 채우기

연속된 k개 원소의 합이 최대인 구간의 합을 구하는 함수.

def max_subarray_sum(nums, k):
    if len(nums) < k:
        return 0

    window_sum = sum(nums[:k])       # (a) 첫 윈도우
    max_sum = window_sum

    for i in range(k, len(nums)):    # (b) k부터 시작
        window_sum += nums[i] - nums[i-k]  # (c) 왼쪽 제거
        if window_sum > max_sum:
            max_sum = window_sum

    return max_sum

슬라이딩 윈도우 핵심 구조

  1. 첫 윈도우: sum(nums[:k])로 초기값 계산
  2. 이동 시작: 첫 윈도우 이미 구했으므로 range(k, len(nums))
  3. 갱신: 오른쪽 추가(nums[i]) - 왼쪽 제거(nums[i-k])

14차에서는 range 시작값에서 힌트가 필요했는데, 이번엔 바로 정답!

2. 슬라이딩 윈도우 — 함수 작성

연속된 k개 원소의 평균이 최대인 구간의 시작 인덱스를 반환하는 함수.

def solution(nums, k):
    std_sum = sum(nums[:k])
    std_idx = 0
    max_sum = std_sum

    for i in range(k, len(nums)):
        std_sum += nums[i] - nums[i-k]
        if std_sum > max_sum:
            max_sum = std_sum
            std_idx = i - k + 1
        
    return std_idx

포인트

  • 합이 최대면 평균도 최대 — k가 고정이니까 나누기 불필요. 불필요한 연산을 줄이는 판단이 좋았다는 피드백을 받았다.
  • 시작 인덱스: i - k + 1 (빠진 원소의 다음 인덱스)
  • > vs >=: 같은 합일 때 앞쪽 인덱스를 유지해야 하므로 >(초과) 사용

수업 중 질문: "첫번째 문제처럼 len(nums) < k인 경우는 없어?"
→ COS Pro 실제 시험에서는 보통 입력 조건이 보장되어 있어서 예외 처리 없이 바로 로직에 집중하면 된다.

3. 문자열 순환 — 빈칸 채우기

문자열을 원형(순환)으로 간주하여 연속된 k글자 중 사전순으로 가장 앞서는 부분 문자열을 반환하는 함수.

def earliest_circular_substring(text, k):
    extended = text * 2            # (a) 순환 처리
    result = extended[:k]

    for i in range(1, len(text)):  # (b) 고유 시작점은 len(text)개
        substring = extended[i:i+k]
        if substring < result:
            result = substring

    return result

순환 처리 핵심

  • text * 2: 문자열을 두 번 이어붙여서 끝을 넘어가는 케이스 해결
  • 순회 범위는 len(text): 원형 문자열에서 고유한 시작점은 원본 길이만큼만 존재

처음에 len(extended) - k로 답했는데, 동작은 하지만 중복 순회가 발생한다. 시험 빈칸 채우기에서는 len(text)가 정답이므로 오답 처리될 수 있다는 피드백을 받았다.

i"dbca"(k=2)비고
0db
1bc
2ca
3ad← 순환으로만 나오는 조합
4dbi=0과 동일 (불필요)
5bci=1과 동일 (불필요)

4. 문자열 순환 — 함수 작성

문자열을 순환으로 간주하여 연속된 k글자로 만들 수 있는 서로 다른 부분 문자열의 개수를 반환하는 함수.

def solution(text, k):
    extended = text * 2
    str_set = set()

    for i in range(0, len(text)):
        sub_str = extended[i:i+k]
        str_set.add(sub_str)
    
    return len(str_set)

포인트

  • set()으로 중복 제거 — "서로 다른 개수"에 딱 맞는 자료구조
  • 앞 문제 피드백을 바로 반영하여 len(text) 범위로 정확히 설정
  • 변수명 str_setstr로 지었으면 내장함수를 덮어쓸 뻔했는데 잘 피함

5. 함수 작성 종합 (1) — 상하위 평균 차이

학생들의 점수에서 상위 k명과 하위 k명의 평균 차이를 반환하는 함수.

def solution(scores, k):
    sorted_scores = sorted(scores)
    high_avg = sum(sorted_scores[-k:]) / k
    low_avg = sum(sorted_scores[:k]) / k

    return high_avg - low_avg

포인트

  • sorted()로 원본 안 건드림 (좋은 습관)
  • [-k:], [:k] 슬라이싱 정확
  • 변수명 sorted_scores — 내장함수명 안 겹침

수업 중 질문: "abs() 감싼다는 건 마지막 return할 때 abs(high_avg - low_avg) 하라는 거야?"
→ 맞다. 이 문제에서는 정렬 후 상위 >= 하위가 보장되지만, "절댓값으로 반환하라"는 조건이 명시된 문제라면 abs()를 감싸는 게 안전하다.

풀이 중 출제자가 제시한 예시 답(35.0)이 틀렸다는 것을 직접 계산해서 발견했다 (정답: 40.0). 검증 습관이 좋다는 피드백을 받았다.

6. 함수 작성 종합 (2) — 모음 최다 단어

문자열 리스트에서 모음(a, e, i, o, u)이 가장 많은 단어를 반환하는 함수.

첫 번째 시도 (버그 있음)

def solution(words):
    lowered_words = [x.lower() for x in words]  # 여기서 원본 소실!
    chk_list = ['a', 'e', 'i', 'o', 'u']
    max_count = 0
    result_word = ""

    for w in lowered_words:  # 소문자 버전을 순회
        ...
        result_word = w      # 소문자 버전이 저장됨

    return result_word

문제: lowered_words를 순회하면서 result_word에 소문자 변환된 값이 저장된다. ["APPLE"] 입력 시 "apple"이 반환됨.

수정 후 (정답)

def solution(words):
    chk_list = ['a', 'e', 'i', 'o', 'u']
    max_count = 0
    result_word = ""

    for w in words:              # 원본을 순회
        cnt = 0
        for ch in w.lower():    # 비교할 때만 소문자로
            if ch in chk_list:
                cnt += 1
        if cnt > max_count:
            max_count = cnt
            result_word = w      # 원본이 저장됨

    return result_word

데이터 변환 시 원본 보존 패턴

방식코드원본 유지
변환 리스트 순회for w in lowered_words:X
원본 순회 + 비교만 변환for w in words: ... w.lower()O

핵심: 비교/검색에만 변환을 쓰고, 결과에는 원본을 저장할 것!

추가로 chk_list 대신 문자열로도 가능하다는 팁을 받았다: if ch in "aeiou"


오늘의 결과

  • 6문제 풀이, 1차 정답률 67% (4/6) — 함수 작성 3/4로 개선 추세 유지
  • 슬라이딩 윈도우 완전 정착, 내장함수명 변수 사용·하드코딩 미발생
  • 다음 학습: 프로그래머스/백준 문제 풀이로 함수 작성 실전 연습 시작
profile
문서화를 좋아하는 개발자

0개의 댓글