Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬으로 투표 데이터에서 최종 순위 계산하기: 높은 순위부터 낮은 순위까지

소문자로만 구성된 문자열 리스트 votes가 있다고 가정해 보겠습니다. 각 항목은 선호도가 가장 높은 순서부터 가장 낮은 순서까지 후보자에게 표현된 투표를 의미합니다.

후보자의 순위는 다음 규칙에 따라 결정됩니다.

  • 먼저 1순위(최고 선호) 득표 수가 많은 순서대로 정렬됩니다.
  • 1순위 득표 수가 같다면, 2순위 득표 수를 비교하고, 그래도 같으면 그다음 선호도 순위의 득표 수를 차례대로 비교합니다.
  • 모든 순위에서 득표 수가 동일하다면, 알파벳 순서로 최종 순위를 매깁니다.

이 규칙을 적용하여 전체 팀(후보)의 최종 순위를 높은 순위부터 낮은 순위까지 구하는 것이 목표입니다.

예시

입력이 votes = ["zyx", "zxy", "xyz"]라면 출력은 "zxy"가 됩니다. 그 이유는 다음과 같습니다.

  • z: 1순위 득표가 2표로 가장 많으므로 1위입니다.
  • x: 1순위 득표가 1표로 두 번째이므로 2위입니다.
  • y: 1순위 득표가 없으므로 3위입니다.

풀이 접근 방법

이 문제는 다음 단계로 해결할 수 있습니다.

  • count := 투표 문자열의 길이 (선호도 순위의 개수)
  • cand := 비어 있는 딕셔너리(map). 각 키(후보)에는 크기가 count인 리스트가 연결되며, 초기값은 모두 0으로 채워집니다.
  • votes의 각 문자열 v에 대해:
    • 각 인덱스 i와 문자 c에 대해 cand[c][i] 값을 1씩 증가시킵니다. 즉, 후보 c가 i+1번째 선호 순위에서 받은 표의 개수를 누적합니다.
  • cand의 항목들을 값 기준 내림차순으로 정렬합니다. 값이 같을 경우 알파벳 순서로 정렬합니다.
  • 정렬된 요소들을 이어 붙여 하나의 문자열로 만들어 반환합니다.

구현 코드

from collections import defaultdict
class Solution:
    def solve(self, votes):
        count = len(votes[0])
        cand = defaultdict(lambda: [0] * count)
        for v in votes:
            for i, c in enumerate(v):
                cand[c][i] += 1
        return "".join(sorted(cand.keys(), key=lambda x: (cand[x], -ord(x)), reverse=True))
        
ob = Solution()
votes = ["zyx", "zxy", "xyz"]
print(ob.solve(votes))

입력

["zyx", "zxy", "xyz"]

출력

zxy

코드 설명

핵심은 마지막 줄의 정렬 로직입니다. 정렬 키인 (cand[x], -ord(x))는 두 부분으로 구성됩니다.

  • cand[x]: 각 선호 순위별 득표 수를 담은 리스트입니다. 파이썬은 리스트를 사전식(lexicographic)으로 비교하므로, 자동으로 1순위 → 2순위 → 3순위 순서로 득표 수를 비교하게 됩니다.
  • -ord(x): 득표 수가 완전히 같을 때 사용되는 타이브레이커입니다. reverse=True와 함께 사용되므로 -ord() 값이 더 큰, 즉 알파벳 순서상 앞선 문자가 먼저 배치됩니다.

이처럼 defaultdict와 파이썬의 다중 조건 정렬을 활용하면 복잡한 순위 규칙도 간결한 코드로 처리할 수 있습니다.