You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

决选投票算法代码问题:无限循环与索引越界排查

决选投票逻辑的问题排查与修复

原代码存在的核心问题

  • 无限循环触发:winner初始值为False,当设置为None时,not winner仍为True,循环不会终止;且当所有候选人得票均为1时,错误地将所有候选人加入排除列表,后续逻辑混乱导致无法跳出循环。
  • 索引越界错误:当所有候选人被排除后,代码仍尝试访问空列表的i[0]元素;且在处理排除候选人时,在for m in exclude循环内直接清空row和exclude,导致后续操作逻辑断裂。
  • 得票统计与淘汰逻辑错误:遍历row时重复统计同一候选人的得票数,导致exclude重复添加相同候选人;错误地将得票为1的候选人全部排除,而非淘汰得票最少的候选人。
  • 数据修改风险:直接将vote = voters,修改vote会同步改动原voters数据,导致后续轮次统计出错。

修复后的完整代码

def runoff(voters):
    # 复制选民数据,避免修改原输入
    current_voters = [voter.copy() for voter in voters]
    total_voters = len(current_voters)
    # 初始化有效候选人集合
    candidates = set()
    for voter in current_voters:
        candidates.update(voter)
    candidates = list(candidates)
    
    while True:
        # 统计当前所有选民的有效首选
        current_votes = []
        for voter in current_voters:
            if voter:
                current_votes.append(voter[0])
        
        # 无有效选票时直接返回None
        if not current_votes:
            winner = None
            break
        
        # 统计各候选人得票数
        vote_counts = {}
        for candidate in candidates:
            vote_counts[candidate] = current_votes.count(candidate)
        
        # 检查是否有候选人获得超过50%的选票
        majority = total_voters / 2
        for candidate, count in vote_counts.items():
            if count > majority:
                winner = candidate
                break
        else:
            # 无胜者,找出得票最少的候选人(可能多个)
            min_votes = min(vote_counts.values())
            to_exclude = [c for c, cnt in vote_counts.items() if cnt == min_votes]
            
            # 更新有效候选人列表
            candidates = [c for c in candidates if c not in to_exclude]
            # 移除每个选民列表中已淘汰的候选人
            for voter in current_voters:
                for excluded in to_exclude:
                    if excluded in voter:
                        voter.remove(excluded)
            # 所有候选人都被淘汰时终止循环
            if not candidates:
                winner = None
                break
            continue
        
        break  # 找到胜者,终止循环
    
    print("The winner is: ", winner)
    return winner

# 测试用例1
runoff([["dem", "ind", "rep"],
        ["rep", "ind", "dem"],
        ["ind", "dem", "rep"],
        ["ind", "rep", "dem"]])

# 测试用例2
runoff([["a", "c", "d", "e", "b"],
        ["e", "b", "d", "c", "a"],
        ["d", "e", "c", "a", "b"],
        ["c", "e", "d", "b", "a"],
        ["b", "e", "a", "c", "d"]])

修复说明

  1. 数据隔离:使用current_voters = [voter.copy() for voter in voters]复制原数据,避免修改输入的原始选民列表。
  2. 正确的多数判定:用count > total_voters / 2判断是否获得超过50%的选票,兼容奇偶选民数场景,避免原代码仅适用于偶数的局限。
  3. 精准淘汰逻辑:统计所有候选人得票数后,找出得票最少的候选人(可能多个)并排除,符合决选投票规则。
  4. 循环终止条件:处理了无有效候选人、无有效选票的情况,直接返回None;找到胜者后立即终止循环,彻底解决无限循环问题。
  5. 索引安全:在访问选民首选前先判断列表是否为空,避免触发IndexError。

内容的提问来源于stack exchange,提问作者Sergey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:51:56