CS50第三周Runoff作业print_winner函数无限循环问题求助
CS50 Runoff作业无限循环问题修复
问题现象
当候选人获得100%第一顺位选票时程序能正常输出胜者,但得票少于100%时会陷入无限循环。例如运行./runoff aa bb cc,若所有选票投给cc可正确输出;但cc得2/3选票时,程序无限循环。
核心问题与修复方案
1. tabulate函数未处理顺位转移
原函数只统计第一顺位的有效选票,忽略了被淘汰候选人后的选票转移逻辑,导致每次计票结果不变,循环无法推进。
修复后的代码:
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; // 找到有效候选人后停止遍历 } } } // 可选保留调试打印 for (int k = 0; k < candidate_count; k++) { printf("DEBUG in tabulate = Candid name - %s, Index no - %d, votes - %d \n",candidates[k].name, k,candidates[k].votes); } }
2. print_winner函数整数除法错误
原代码用整数除法计算得票率,导致非100%的得票率被截断为0,永远无法满足kk>50的获胜条件。直接比较票数是否超过半数更准确。
修复后的代码:
bool print_winner(void) { for (int j = 0; j < candidate_count; j++) { // 判断是否超过半数选票 if (candidates[j].votes > voter_count / 2) { printf("%s\n", candidates[j].name); return true; } } return false; }
3. find_min函数错误排序候选人数组
冒泡排序会打乱候选人的原始顺序,导致后续操作与preferences数组的索引对应错误。正确做法是遍历未被淘汰的候选人找最小得票数。
修复后的代码:
int find_min(void) { int min_votes = voter_count; // 初始化为最大可能票数 for (int i = 0; i < candidate_count; i++) { if (!candidates[i].eliminated && candidates[i].votes < min_votes) { min_votes = candidates[i].votes; } } return min_votes; }
4. is_tie函数逻辑错误与数组越界
原代码存在数组越界访问candidates[candidate_count],且平局判断逻辑错误。正确逻辑是所有未被淘汰的候选人得票数都等于最小值。
修复后的代码:
bool is_tie(int min) { for (int i = 0; i < candidate_count; i++) { // 存在未被淘汰且得票不等于最小值的候选人,不是平局 if (!candidates[i].eliminated && candidates[i].votes != min) { return false; } } return true; }
5. vote函数的rank限制错误
原代码限制rank < 3,但候选人数量可能超过3,导致后续rank的投票被判定为无效。
修复后的代码片段:
// 替换原条件中的rank < 3为rank < candidate_count if (voter < voter_count && rank < candidate_count)
内容的提问来源于stack exchange,提问作者Vid
相关产品推荐
相关产品推荐

