【问题标题】:CS50 pset3 RunoffCS50 pset3 径流
【发布时间】:2020-09-04 15:42:15
【问题描述】:

我在 CS50 pset3 Runoff 的一开始就被卡住了。我使用了几种外部资源,但没有任何意义。请帮帮我,这集让我因为不明白而要退出。

以下是说明:

  • 该函数接受参数 voter、rank 和 name。如果 name 与有效候选人的名字匹配,那么您应该更新全局首选项数组以指示选民选民将该候选人作为他们的排名首选项(其中 0 是第一个首选项,1 是第二个首选项,等等。 )。
  • 如果偏好记录成功,函数应该返回true;否则该函数应返回 false(例如,如果 name 不是候选人之一的姓名)。
  • 您可以假设没有两个候选人的名字相同。

这是我的代码:

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

// Max voters and candidates
#define MAX_VOTERS 100
#define MAX_CANDIDATES 9

// preferences[i][j] is jth preference for voter i
int preferences[MAX_VOTERS][MAX_CANDIDATES];

// Candidates have name, vote count, eliminated status
typedef struct
{
    string name;
    int votes;
    bool eliminated;
}
candidate;

// Array of candidates
candidate candidates[MAX_CANDIDATES];

// Numbers of voters and candidates
int voter_count;
int candidate_count;

// Function prototypes
bool vote(int voter, int rank, string name);
void tabulate(void);
bool print_winner(void);
int find_min(void);
bool is_tie(int min);
void eliminate(int min);

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

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

    voter_count = get_int("Number of voters: ");
    if (voter_count > MAX_VOTERS)
    {
        printf("Maximum number of voters is %i\n", MAX_VOTERS);
        return 3;
    }

    // Keep querying for votes
    for (int i = 0; i < voter_count; i++)
    {

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

            // Record vote, unless it's invalid
            if (!vote(i, j, name)) // if vote bool is Not true
            {
                printf("Invalid vote.\n");
                return 4;
            }
        }

        printf("\n");
    }

    // Keep holding runoffs until winner exists
    while (true)
    {
        // Calculate votes given remaining candidates
        tabulate();

        // Check if election has been won
        bool won = print_winner();
        if (won)
        {
            break;
        }

        // Eliminate last-place candidates
        int min = find_min();
        bool tie = is_tie(min);

        // If tie, everyone wins
        if (tie)
        {
            for (int i = 0; i < candidate_count; i++)
            {
                if (!candidates[i].eliminated)
                {
                    printf("%s\n", candidates[i].name);
                }
            }
            break;
        }

        // Eliminate anyone with minimum number of votes
        eliminate(min);

        // Reset vote counts back to zero
        for (int i = 0; i < candidate_count; i++)
        {
            candidates[i].votes = 0;
        }
    }
    return 0;
}

// Record preference if vote is valid
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]++;
            return true;

        }

    }


// TO DO
    return false;
}



【问题讨论】:

标签: c cs50


【解决方案1】:

您的vote 函数中存在一个您可能忽略的错误。如果选民的输入是有效的候选人姓名,您希望将候选人索引放在首选项数组中,而不仅仅是添加到该选民的首选项中。请记住:vote 函数只是更新选民排名的偏好,而tabulate 函数是您实际统计所有候选人投票的地方。

这是我的意思的一个例子。想象一下有三名候选人的决选:爱丽丝、鲍勃和查理。这意味着候选数组将 Alice 存储在零索引中,Bob 作为第一个索引,Charlie 作为第二个索引。现在假设第一个选民将 Bob 作为他们的首选候选人,Charlie 作为他们的第二个首选候选人,而 Alice 作为他们的最后选择。根据您的功能,您的 preferences[0] 将存储一个包含元素 {1, 1, 1} 的数组,因为您每次说 preferences[voter][rank]++; 时只是将 1 添加到一个空的首选项数组中。您希望在preferences[0] 中拥有一个包含元素 {1, 2, 0} 的数组。这是因为选民的第一选择是 Bob,也就是 candidates[1],他们的第二选择是 Charlie,也就是 candidates[2],他们的第三选择是 Alice,也就是 candidates[0]

因此,通过遍历候选人列表,您将通过变量i 获得要添加的候选人的正确索引,因此只需将您的代码行更改为preferences[voter][rank] = i;

您的vote 函数应如下所示:

// Record preference if vote is valid
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;
}

PS:单步调试 debug50 是解决这类问题的绝佳工具。

PPS:我希望你已经解决了这个问题,但如果还没有,我希望你继续完成这门课程。问题集具有挑战性,但完成后值得。

您好@user13569450,如果此答案或任何答案解决了您的问题,请单击复选标记考虑accepting it。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。

【讨论】:

    猜你喜欢
    • 2022-12-22
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    相关资源
    最近更新 更多