문제 링크

문제 요약

주어진 암호화된 메시지 텍스트에서 공백과 개행 문자를 제외한 모든 문자의 출현 빈도를 세어 히스토그램 형태로 출력하는 문제입니다. 히스토그램은 각 문자의 출현 횟수만큼 # 문자로 이루어진 수직 막대로 표현되며, 모든 막대의 밑동은 같은 줄에 정렬되어야 합니다. 막대 아래에는 해당 문자를 출력하며, 막대들은 문자 코드(ASCII 값) 오름차순으로 정렬되어야 합니다.

풀이

이 문제는 주어진 텍스트에서 특정 문자의 빈도를 세고, 이를 시각적으로 히스토그램 형태로 출력하는 구현 문제입니다. 다음 단계를 통해 해결할 수 있습니다.

  1. 입력 텍스트 처리: 입력은 여러 줄로 주어질 수 있으며, 파일의 끝(EOF)까지 읽어야 합니다. 또한 공백(space)과 개행(newline) 문자는 히스토그램에 포함되지 않으므로, 이들을 제외한 모든 문자를 하나의 문자열로 모아야 합니다.

    • 제공된 코드에서는 while 1: try: ... except: break 구문을 사용하여 sys.stdin에서 모든 라인을 읽어옵니다. inp() 함수는 각 라인에서 개행 문자를 제거합니다.
    • 이후 s = s.replace(" ", "")를 통해 문자열 s에서 모든 공백 문자를 제거합니다. 이렇게 하면 최종 s 문자열에는 히스토그램을 그릴 대상 문자들만 남게 됩니다.
  2. 문자 빈도 계산 및 정렬:

    • collections.Counter를 사용하여 문자열 s에 있는 각 문자의 빈도를 효율적으로 계산합니다.
    • 히스토그램의 열 순서는 문자 코드 오름차순이어야 하므로, set(s)를 통해 고유한 문자들을 얻은 후 sorted() 함수로 정렬하여 uniq_s 리스트를 만듭니다.
  3. 히스토그램 최대 높이 결정: max(cnt.values())를 통해 가장 많이 출현한 문자의 빈도를 찾아 히스토그램의 최대 높이(max_cnt)를 결정합니다. 이 높이가 히스토그램을 그릴 행의 수가 됩니다.

  4. 히스토그램 출력:

    • 히스토그램은 위에서 아래로 그려지므로, max_cnt부터 1까지 역순으로 반복하면서 각 행을 구성합니다. (예: for i in range(max_cnt, 0, -1):)
    • 각 행에서는 uniq_s에 저장된 정렬된 문자들을 순서대로 순회합니다.
    • 현재 문자의 빈도 cnt[c]가 현재 행의 높이 i보다 크거나 같으면, 해당 문자가 이 높이까지 막대를 형성한다는 의미이므로 #를 출력합니다.
    • 그렇지 않으면, 해당 문자의 막대는 이 높이까지 도달하지 않으므로 공백( )을 출력합니다.
    • 하나의 행 출력이 끝나면 개행합니다.
  5. 문자 라벨 출력: 모든 히스토그램 막대가 출력된 후, 마지막 줄에는 uniq_s에 저장된 정렬된 문자들을 그대로 출력하여 각 막대가 어떤 문자에 해당하는지 표시합니다.

정답 코드

def solve():
  s = ""
  while 1:
    try:
      line = input()
      s += line
    except:
      break
 
  s = s.replace(" ", "")
  uniq_s = sorted(list(set(s)))
  cnt = Counter(s)
  max_cnt = max(cnt.values())
 
  for i in range(max_cnt, 0, -1):
    for c in uniq_s:
      if cnt[c] >= i:
        print(end="#")
      else:
        print(end=" ")
    print()
  
  print("".join(uniq_s))
 
 
if __name__ == "__main__":
  tc = 1
  for t in range(1, tc+1):
    ret = solve()
 

연관 페이지

참고 문헌 / 사이트