CS50决选程序print_winner无法终止无限循环问题求助
CS50决选选举程序循环无法终止的问题排查
这不是未完成代码的正常现象,你的程序存在明确bug,核心问题出在选票记录和计票逻辑上,以下是具体排查方向和修复点:
1. vote函数的致命逻辑错误
你当前的vote函数循环遍历的是voter_count(选民数量),但实际应该遍历candidate_count(候选人数量)——你要做的是验证选票上的名字是否属于候选人,而非遍历选民。这个错误直接导致大量选票无法被正确记录到preferences数组,后续计票完全失真。
修复代码:
bool vote(int voter, int rank, string name) { for (int i = 0; i < candidate_count; i++) // 遍历候选人而非选民 { if (strcmp(name, candidates[i].name) == 0) { preferences[voter][rank] = i; return true; } } return false; }
2. tabulate函数的计票逻辑完全颠倒
这个函数是计票核心,当前逻辑存在两个严重问题:
- 找到未被淘汰的候选人时直接break,完全没给该候选人加票;反而给被淘汰候选人的下一名加票,逻辑完全反转
- 多余的数组长度计算
int lenght = sizeof(preferences) / sizeof(preferences[0]);毫无意义,voter_count已经是输入的选民总数
修复后的正确计逻辑:
void tabulate(void) { for (int i = 0; i < voter_count; i++) { for (int j = 0; j < candidate_count; j++) { int candidate_idx = preferences[i][j]; if (!candidates[candidate_idx].eliminated) { candidates[candidate_idx].votes++; // 给有效候选人加票 break; // 找到该选民的有效票后停止遍历 } } } }
3. 辅助调试验证
修复前两个问题后,可以在tabulate()函数执行后添加调试打印,输出每个候选人的得票数,确认是否达到超过半数的条件:
// 在tabulate()之后添加 for (int i = 0; i < candidate_count; i++) { printf("%s: %d votes\n", candidates[i].name, candidates[i].votes); }
4. 关于未完成函数的说明
虽然find_min、is_tie、eliminate还未实现,但在第一轮就有候选人得票超过半数的场景下,程序会在print_winner()返回true后直接break循环,不会执行到这些函数。所以当前循环无法终止的核心原因并非这些未完成函数,而是前面的选票记录和计票错误导致print_winner()始终返回false。
内容的提问来源于stack exchange,提问作者GirlSM
相关产品推荐
相关产品推荐

