简体   繁体   中英

CS50 pset3 Runoff

I'm stuck at the very beginning on the CS50 pset3 Runoff. Ive used several external resources but nothing is making sense. Please help me, this set has me about to quit because I do not understand.

Here are the instructions:

  • The function takes arguments voter, rank, and name. If name is a match for the name of a valid candidate, then you should update the global preferences array to indicate that the voter voter has that candidate as their rank preference (where 0 is the first preference, 1 is the second preference, etc.).
  • If the preference is successfully recorded, the function should return true; the function should return false otherwise (if, for instance, name is not the name of one of the candidates).
  • You may assume that no two candidates will have the same name.

Here is my code:

#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;
}



There is one mistake in your vote function that you may have overlooked. If the voter's input is a valid candidate name, you want to put the candidates index in the preferences array, not just add on to that voters preference. Remember: the vote function simply updates the voters ranked preferences, whereas the tabulate function is where you actually tally up all the candidates votes.

Here's an example of what I mean. Imagine a runoff election with three candidates: Alice, Bob and Charlie. This means that the candidates array will store Alice in the zero index, Bob as the first index, and Charlie as the second index. Now imagine that the first voter has Bob as their preferred candidate, Charlie as their second preferred candidate, and Alice as their last choice. According to your function, your preferences[0] will store an array with the elements {1, 1, 1}, because you are simply adding 1 to an empty preferences array every time that you say preferences[voter][rank]++; . What you want to have in preferences[0] is an array with the elements {1, 2, 0}. This is because the voter's first choice is Bob, aka candidates[1] , their second choice is Charlie, aka candidates[2] and their third choice is Alice, aka candidates[0] .

So, by looping through the candidates list, you are getting the proper index of the candidate you want to add via the variable i , so simply change your line of code to preferences[voter][rank] = i; .

Your vote function should look like this:

// 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: Stepping through debug50 is an excellent tool to use in these types of problems.

PPS: I hope you've already gotten past this problem but if not, I hope that you continue working through the course. The problem sets are challenging, but are worth it when you complete them.

Hi @user13569450 if this or any answer has solved your question please consider accepting it by clicking the check-mark. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. There is no obligation to do this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM