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

CS50 Tideman项目:sort_pairs函数无法正常返回,求排查指导

解决CS50 Tideman项目sort_pairs函数排序异常问题

问题描述

在完成CS50的Tideman项目时,vote、record_preferences、add_pairs函数均通过测试,但sort_pairs函数无法正常完成排序。以下是完整项目代码:

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

// Max number of candidates
#define MAX 9

// preferences[i][j] is number of voters who prefer i over j
int preferences[MAX][MAX];

// locked[i][j] means i is locked in over j
bool locked[MAX][MAX];

// Each pair has a winner, loser
typedef struct
{
    int winner;
    int loser;
} pair;

// Array of candidates
string candidates[MAX];
pair pairs[MAX * (MAX - 1) / 2];

int pair_count;
int candidate_count;

// Function prototypes
bool vote(int rank, string name, int ranks[]);
void record_preferences(int ranks[]);
void add_pairs(void);
void sort_pairs(void);
void lock_pairs(void);
void print_winner(void);

int main(int argc, string argv[])
{
    // Check for invalid usage
    if (argc < 2)
    {
        printf("Usage: tideman [candidate ...]\n");
        return 1;
    }

    // Populate array of candidates
    candidate_count = argc - 1;
    if (candidate_count > MAX)
    {
        printf("Maximum number of candidates is %i\n", MAX);
        return 2;
    }
    for (int i = 0; i < candidate_count; i++)
    {
        candidates[i] = argv[i + 1];
    }

    // Clear graph of locked in pairs
    for (int i = 0; i < candidate_count; i++)
    {
        for (int j = 0; j < candidate_count; j++)
        {
            locked[i][j] = false;
        }
    }

    pair_count = 0;
    int voter_count = get_int("Number of voters: ");

    // Query for votes
    for (int i = 0; i < voter_count; i++)
    {
        // ranks[i] is voter's ith preference
        int ranks[candidate_count];

        // Query for each rank
        for (int j = 0; j < candidate_count; j++)
        {
            string name = get_string("Rank %i: ", j + 1);

            if (!vote(j, name, ranks))
            {
                printf("Invalid vote.\n");
                return 3;
            }
        }

        record_preferences(ranks);

        printf("\n");
    }

    add_pairs();
    sort_pairs();
    lock_pairs();
    print_winner();
    return 0;
}

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

    return false;
}

// Update preferences given one voter's ranks
// DONE
void record_preferences(int ranks[])
{
    //sequence through ranks[] array
    for(int i = 0; i < candidate_count; i++)
    {
        //compare i-th locations in ranks[] to determine ranking
        for(int j = 0; j < candidate_count; j++)
        {
            if((i < j) && (i != j))
            {
                preferences[ranks[i]][ranks[j]]++;
            }

            else
            {
                continue;
            }
        }
    }
    return;
}

// Record pairs of candidates where one is preferred over the other
// DONE
void add_pairs(void)
{
    for(int i = 0; i < candidate_count; i++)
    {
        for(int j = i + 1; j < candidate_count; j++)
        {
          if(preferences[i][j] > preferences[j][i])
            {
                pairs[pair_count].winner = i;
                pairs[pair_count].loser = j;
                pair_count++;
            }
            else if(preferences[i][j] < preferences[j][i])
            {
                pairs[pair_count].winner = j;
                pairs[pair_count].loser = i;
                pair_count++;
            }
        }

    }
    return;
}

// Sort pairs in decreasing order by strength of victory
void sort_pairs(void)
{
    // TODO
    // Initialize variables and arrays for sorting
    int max = 0;
    int loc = 0;
    pair temp[1];
    // Selection sort pairs
    for(int i = 0; i < pair_count; i++)
    {
        max = preferences[pairs[i].winner][pairs[i].loser];
        for(int j = i; j < pair_count; j++)
        {
            if(preferences[pairs[j].winner][pairs[j].loser] > max)
            {
                max = preferences[pairs[j].winner][pairs[j].loser];
                loc = j;
            }
        }
        temp[0] = pairs[i];
        pairs[i] = pairs[loc];
        pairs[loc] = temp[0];
        printf("%i\n", pairs[i].winner);
    }
}

错误根源分析

sort_pairs函数采用选择排序逻辑,但存在一个关键错误:

  • loc变量在函数开头初始化后,没有在每次外层循环时重置为当前的i。当某次外层循环中,从i到pair_count-1的范围内没有比当前pairs[i]胜利强度更大的元素时,loc会保留上一次循环的位置,导致错误地交换元素,破坏排序结果。

修复后的sort_pairs函数

只需在每次外层循环开始时,将loc重置为当前的i,确保初始候选最大值的位置正确:

// Sort pairs in decreasing order by strength of victory
void sort_pairs(void)
{
    // Initialize variables and arrays for sorting
    int max = 0;
    int loc; // 不再提前初始化,放到循环内
    pair temp; // 不需要数组,单个结构体即可
    // Selection sort pairs
    for(int i = 0; i < pair_count; i++)
    {
        loc = i; // 每次外层循环重置loc为当前i
        max = preferences[pairs[i].winner][pairs[i].loser];
        for(int j = i; j < pair_count; j++)
        {
            if(preferences[pairs[j].winner][pairs[j].loser] > max)
            {
                max = preferences[pairs[j].winner][pairs[j].loser];
                loc = j;
            }
        }
        // 交换当前i位置和最大值位置的元素
        temp = pairs[i];
        pairs[i] = pairs[loc];
        pairs[loc] = temp;
    }
}

额外优化:将temp从数组改为单个pair结构体,更符合逻辑且节省空间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 13:52:33