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

CS50x Pset3 Tideman:vote与preferences函数check50报错求助

CS50x Pset3 Tideman:vote与record_preferences函数问题排查

问题描述

我在完成CS50x的Pset3 Tideman题目时,编写了vote和record_preferences函数的代码,但运行check50时出现以下问题:

  • vote函数未正确设置ranks数组
  • 首个投票者的preferences未被正确设置

不过后续测试显示,record_preferences能为其他投票者正确设置preferences,依赖该数组的其他功能也可正常运行。我发现测试期望ranks数组按ranks[rank] = i的方式使用,自己用printf检查preferences的每行数据看起来是正确的,不清楚问题出在哪。

我的代码如下:

// Update ranks given a new vote
bool vote(int rank, string name, int ranks[])
{
    // TODO
    for (int i = 0; i < candidate_count; i++)
    {
        if (strcasecmp(name, candidates[i]) == 0)
        {
            ranks[i] = rank;
            rank++;
            return true;
        }
    }
    return false;
}

// Update preferences given one voter's ranks
void record_preferences(int ranks[])
{
    // TODO
   for (int i = 0; i < candidate_count; i++)
    {
        for (int j = 0; j < candidate_count; j++)
        {
            // reverse logic when comparing ranks, because rank 0 is greater than rank 1 etc..
            if(ranks[i] < ranks[j])
            preferences[i][j]++;
        }
    }
}

问题根源

你的vote函数完全搞反了ranks数组的定义逻辑:
题目要求ranks数组的作用是以投票优先级为下标,存储对应优先级的候选人索引——比如ranks[0]代表该投票者最支持的候选人的编号,ranks[1]代表次支持的,以此类推。但你现在的写法是ranks[i] = rank,也就是把候选人索引i作为下标,存储该候选人对应的投票优先级,这和题目定义的数组用途完全相反。

虽然你的record_preferences函数适配了这个反向的ranks数组(通过比较ranks[i] < ranks[j]来判断候选人i的优先级更高),但check50的测试用例是严格按照题目规定的ranks数组格式来校验的,所以vote函数的测试直接失败;同时首个投票者的preferences因为vote的错误初始化没通过测试,后续投票者可能因测试用例巧合或逻辑适配了反向数组,才看起来正常。

修正方案

1. 修正vote函数

把数组赋值逻辑改成题目要求的格式,同时去掉多余的rank++(vote函数仅处理单个rank的投票选择,rank递增由调用逻辑处理):

// Update ranks given a new vote
bool vote(int rank, string name, int ranks[])
{
    for (int i = 0; i < candidate_count; i++)
    {
        if (strcasecmp(name, candidates[i]) == 0)
        {
            ranks[rank] = i; // 以优先级rank为下标,存储对应的候选人索引i
            return true;
        }
    }
    return false;
}

2. 修正record_preferences函数

因为ranks数组逻辑改回了正确格式,需要调整preferences的统计逻辑,这里提供两种高效写法:

写法一:利用优先级顺序直接统计

// Update preferences given one voter's ranks
void record_preferences(int ranks[])
{
    for (int i = 0; i < candidate_count; i++)
    {
        // 当前优先级i对应的候选人
        int top_candidate = ranks[i];
        // 遍历所有优先级低于i的候选人
        for (int j = i + 1; j < candidate_count; j++)
        {
            int lower_candidate = ranks[j];
            // 标记当前投票者认为top_candidate比lower_candidate更优
            preferences[top_candidate][lower_candidate]++;
        }
    }
}

这个写法直接利用rank的顺序(0是最高优先级),每个高优先级的候选人都比所有低优先级的候选人更优,逻辑清晰且高效。

写法二:通过查找优先级比较

// 辅助函数:根据候选人索引获取其对应的投票优先级
int get_candidate_rank(int ranks[], int candidate)
{
    for (int k = 0; k < candidate_count; k++)
    {
        if (ranks[k] == candidate)
        {
            return k;
        }
    }
    return candidate_count; // 返回一个比所有优先级都大的值,表示未找到
}

// Update preferences given one voter's ranks
void record_preferences(int ranks[])
{
    for (int i = 0; i < candidate_count; i++)
    {
        int rank_i = get_candidate_rank(ranks, i);
        for (int j = 0; j < candidate_count; j++)
        {
            int rank_j = get_candidate_rank(ranks, j);
            // 如果候选人i的优先级比j高(rank_i更小)
            if (rank_i < rank_j)
            {
                preferences[i][j]++;
            }
        }
    }
}

这个写法更直观,通过辅助函数获取每个候选人的优先级,再比较大小统计偏好关系。

验证

修正后的代码符合题目对ranks数组的定义,check50的测试用例可以正常通过,同时preferences数组的统计逻辑也完全正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 01:25:02