check50检测print_winner函数失败,请求排查Charlie案例问题
排查print_winner函数未通过Charlie案例检测的问题
问题背景
需要实现print_winner函数,功能为:找出得票最高的候选人并打印其姓名;若多名候选人得票相同,则打印所有相关候选人姓名。check50检测结果如下:
- :) print_winner identifies Alice as winner of election
- :) print_winner identifies Bob as winner of election
- :( print_winner identifies Charlie as winner of election
print_winner function did not print winner of election - :) print_winner prints multiple winners in case of tie
- :) print_winner prints all names when all candidates are tied
用户的实现代码:
void print_winner(void) { int lenght = sizeof(candidates[0].votes); for (int i = 1; i < lenght - 1 ; i++) { if (candidates[0].votes <= candidates[i].votes) { candidates[0].votes = candidates[i].votes; } if (candidates[0].votes == candidates[i].votes) { printf("%s\n", candidates[i].name); } } printf("%s\n", candidates[0].name); return; }
错误原因分析
- 候选人数量获取错误:
sizeof(candidates[0].votes)计算的是单个候选人votes变量的字节大小(比如int类型通常是4字节),完全不是候选人的总数。在该场景中,候选人总数是全局变量n,应该用n来遍历所有候选人。 - 破坏原始数据:循环中直接修改
candidates[0].votes的值,会覆盖原始候选人的得票数据,导致后续判断逻辑混乱。 - 循环逻辑错误:
- 循环范围错误,无法保证遍历到所有候选人(比如Charlie如果是第三个候选人,索引为2,当
lenght=4时,i < 3虽然能遍历到i=2,但逻辑已被修改原始数据破坏)。 - 最后额外打印
candidates[0].name,会导致即使Charlie是唯一最高票,也会多打印Alice的名字(因为之前已把Alice的票数改成Charlie的了),或者根本没遍历到Charlie就结束循环。
- 循环范围错误,无法保证遍历到所有候选人(比如Charlie如果是第三个候选人,索引为2,当
修正后的代码
正确逻辑是先遍历一次找到最高票数,再遍历所有候选人打印得票等于最高票数的:
void print_winner(void) { // 先找出最高票数 int max_votes = 0; for (int i = 0; i < n; i++) { if (candidates[i].votes > max_votes) { max_votes = candidates[i].votes; } } // 遍历所有候选人,打印得票等于最高票数的 for (int i = 0; i < n; i++) { if (candidates[i].votes == max_votes) { printf("%s\n", candidates[i].name); } } return; }
内容的提问来源于stack exchange,提问作者afro_guts
相关产品推荐
相关产品推荐

