문제 링크
문제 요약
주어진 암호화된 메시지 텍스트에서 공백과 개행 문자를 제외한 모든 문자의 출현 빈도를 세어 히스토그램 형태로 출력하는 문제입니다.
히스토그램은 각 문자의 출현 횟수만큼 #
문자로 이루어진 수직 막대로 표현되며, 모든 막대의 밑동은 같은 줄에 정렬되어야 합니다.
막대 아래에는 해당 문자를 출력하며, 막대들은 문자 코드(ASCII 값) 오름차순으로 정렬되어야 합니다.
풀이
이 문제는 주어진 텍스트에서 특정 문자의 빈도를 세고, 이를 시각적으로 히스토그램 형태로 출력하는 구현 문제입니다. 다음 단계를 통해 해결할 수 있습니다.
-
입력 텍스트 처리: 입력은 여러 줄로 주어질 수 있으며, 파일의 끝(EOF)까지 읽어야 합니다. 또한 공백(space)과 개행(newline) 문자는 히스토그램에 포함되지 않으므로, 이들을 제외한 모든 문자를 하나의 문자열로 모아야 합니다.
- 제공된 코드에서는
while 1: try: ... except: break
구문을 사용하여sys.stdin
에서 모든 라인을 읽어옵니다.inp()
함수는 각 라인에서 개행 문자를 제거합니다. - 이후
s = s.replace(" ", "")
를 통해 문자열s
에서 모든 공백 문자를 제거합니다. 이렇게 하면 최종s
문자열에는 히스토그램을 그릴 대상 문자들만 남게 됩니다.
- 제공된 코드에서는
-
문자 빈도 계산 및 정렬:
collections.Counter
를 사용하여 문자열s
에 있는 각 문자의 빈도를 효율적으로 계산합니다.- 히스토그램의 열 순서는 문자 코드 오름차순이어야 하므로,
set(s)
를 통해 고유한 문자들을 얻은 후sorted()
함수로 정렬하여uniq_s
리스트를 만듭니다.
-
히스토그램 최대 높이 결정:
max(cnt.values())
를 통해 가장 많이 출현한 문자의 빈도를 찾아 히스토그램의 최대 높이(max_cnt
)를 결정합니다. 이 높이가 히스토그램을 그릴 행의 수가 됩니다. -
히스토그램 출력:
- 히스토그램은 위에서 아래로 그려지므로,
max_cnt
부터 1까지 역순으로 반복하면서 각 행을 구성합니다. (예:for i in range(max_cnt, 0, -1):
) - 각 행에서는
uniq_s
에 저장된 정렬된 문자들을 순서대로 순회합니다. - 현재 문자의 빈도
cnt[c]
가 현재 행의 높이i
보다 크거나 같으면, 해당 문자가 이 높이까지 막대를 형성한다는 의미이므로#
를 출력합니다. - 그렇지 않으면, 해당 문자의 막대는 이 높이까지 도달하지 않으므로 공백(
- 하나의 행 출력이 끝나면 개행합니다.
- 히스토그램은 위에서 아래로 그려지므로,
-
문자 라벨 출력: 모든 히스토그램 막대가 출력된 후, 마지막 줄에는
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()