CS50x 2024-tideman_test.c 未编译

问题描述 投票:0回答:1

check50 无法编译 foamman.c(完整错误这里) tidman.c 本身编译得很好(无论是在本地使用

make
还是在 check50 中),但 mudderman_test.c 却不能:

running clang tideman.c -o tideman -std=c11 -ggdb -lm -lcs50...
running clang tideman_test.c -o tideman_test -std=c11 -ggdb -lm -lcs50...
tideman_test.c:220:16: error: use of undeclared identifier 'main_id'
while (main_id < left_half_size + right_half_size)
^
tideman_test.c:235:27: error: use of undeclared identifier 'main_id'
tmp_pairs[main_id] = left_half[left_id];
^
tideman_test.c:239:21: error: use of undeclared identifier 'main_id'
main_id += 1;
^
tideman_test.c:240:31: error: use of undeclared identifier 'main_id'
tmp_pairs[main_id] = right_half[right_id];
^
tideman_test.c:246:27: error: use of undeclared identifier 'main_id'
tmp_pairs[main_id] = right_half[right_id];
^
tideman_test.c:249:13: error: use of undeclared identifier 'main_id'
main_id += 1;
^
6 errors generated.

我在 Reddit 和 SOF 上浏览了一堆类似的帖子,其中常见的原因是更改了预先声明的原型或 main 中的一些代码,但在比较我的 titeman.c 的第一个版本和最新版本时我只能看到是:

  • 代码代替
    //TODO
    占位符
  • 新功能(和相关原型)

需要明确的是,错误是由于tigeman_test.c未编译,但该文件仅在CS50一侧,我没有这样的文件。错误的代码确实来自http://tideman.c

完整的潮人.c:

#include <cs50.h>
#include <stdio.h>
#include <string.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);
bool merge_sort_pairs(pair *pairs, int pairs_size);
int get_pair_score(pair pair);
bool is_adding_pair_creating_a_loop(pair pair_to_add);

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
bool vote(int rank, string name, int ranks[])
{
    for (int i = 0; i < candidate_count; i++)
    {
        // Candidate found
        if (strcmp(name, candidates[i]) == 0)
        {
            ranks[rank] = i;
            return true;
        }
    }
    return false;
}

// Update preferences given one voter's ranks
void record_preferences(int ranks[])
{
    for (int i = 0; i < candidate_count - 1; i++)
    {
        int stronger_candidate_id = ranks[i];
        // Then count
        for (int j = i + 1; j < candidate_count; j++)
        {
            int lesser_candidate_id = ranks[j];
            preferences[stronger_candidate_id][lesser_candidate_id] += 1;
        }
    }
    return;
}

// Record pairs of candidates where one is preferred over the other
void add_pairs(void)
{
    // Scan the array up to size/2 (rounded up)
    // Unnecessary: int array_half_size = ceil(candidate_count / 2.0);
    for (int i = 0; i < candidate_count - 1; i++)
    {
        for (int j = i + 1; j < candidate_count; j++)
        {
            // i preferred over j
            if (preferences[i][j] > preferences[j][i])
            {
                pair new_pair;
                new_pair.winner = i;
                new_pair.loser = j;
                pairs[pair_count] = new_pair;
                pair_count += 1;
            }
            // j preferred over i
            else if (preferences[i][j] < preferences[j][i])
            {
                pair new_pair;
                new_pair.winner = j;
                new_pair.loser = i;
                pairs[pair_count] = new_pair;
                pair_count += 1;
            }
            // else do nothing
        }
    }
    return;
}

int get_pair_score(pair pair)
{
    return preferences[pair.winner][pair.loser];
}

// Sort pairs in decreasing order by strength of victory
void sort_pairs(void)
{
    merge_sort_pairs(pairs, pair_count);
    return;
}

bool merge_sort_pairs(pair *pairs_to_sort, int pairs_to_sort_size)
{
    if (pairs_to_sort_size == 1)
    {
        return true;
    }
    else
    {
        int left_half_size = pairs_to_sort_size / 2;
        int right_half_size;
        if (pairs_to_sort_size % 2 == 0)
        {
            right_half_size = pairs_to_sort_size / 2;
        }
        else
        {
            right_half_size = pairs_to_sort_size / 2 + 1;
        }
        // 1. Sort left half
        pair left_half[left_half_size];
        for (int i = 0; i < left_half_size; i++)
        {
            left_half[i] = pairs_to_sort[i];
        }
        merge_sort_pairs(left_half, left_half_size);

        // 2. Sort right half
        pair right_half[right_half_size];
        for (int i = 0; i < right_half_size; i++)
        {
            right_half[i] = pairs_to_sort[left_half_size + i];
        }
        merge_sort_pairs(right_half, right_half_size);

        // 3. Merge
        pair tmp_pairs[left_half_size + right_half_size];
        int left_id = 0;
        int right_id = 0;
        int main_id = 0;
        int left_pair_score = get_pair_score(left_half[left_id]);
        int right_pair_score = get_pair_score(right_half[right_id]);
        while (main_id < left_half_size + right_half_size)
        {
            // Don't overflow
            if (left_id < left_half_size)
            {
                left_pair_score = get_pair_score(left_half[left_id]);
            }
            if (right_id < right_half_size)
            {
                right_pair_score = get_pair_score(right_half[right_id]);
            }

            // Compare scores (but if left half is exhausted, just add right half)
            if (left_pair_score >= right_pair_score && left_id < left_half_size)
            {
                tmp_pairs[main_id] = left_half[left_id];
                left_id += 1;
                if (left_pair_score == right_pair_score)
                {
                    main_id += 1;
                    tmp_pairs[main_id] = right_half[right_id];
                    right_id += 1;
                }
            }
            else
            {
                tmp_pairs[main_id] = right_half[right_id];
                right_id += 1;
            }
            main_id += 1;
        }
        // Copy tmp_pairs back into pairs
        for (int i = 0; i < pair_count; i++)
        {
            pairs[i] = tmp_pairs[i];
        }
        return true;
    }
}

bool is_new_loser_on_top_of_new_winner(int new_winner, int new_loser)
{
    // Check if adding pair_to_add will create a loop in locked
    // 1. Get all candidates that beat new_winner
    int number_of_direct_stronger_candidates = 0;
    int direct_stronger_candidates[MAX - 1];
    for (int i = 0; i < MAX; i++)
    {
        // Lock in the second index which is where candidate i is a loser
        if (locked[i][new_winner] == true)
        {
            if (i == new_loser)
            {
                return true;
            }
            else
            {
                is_new_loser_on_top_of_new_winner(i, new_loser);
            }
        }
    }
    return false;
}

// Lock pairs into the candidate graph in order, without creating cycles
void lock_pairs(void)
{

    // Then start filling it out
    for (int i = 0; i < pair_count; i++)
    {
        pair pair_to_add = pairs[i];
        if (!is_new_loser_on_top_of_new_winner(pair_to_add.winner, pair_to_add.loser))
        {
            // Add pair_to_add
            locked[pair_to_add.winner][pair_to_add.loser] = true;
        }
    }
    return;
}

// Print the winner of the election
void print_winner(void)
{
    for (int i = 0; i < MAX; i++)
    {
        bool i_is_unbeaten = true;
        for (int j = 0; j < MAX; j++)
        {
            // If j has an edge over i, i is not a winner
            if (locked[j][i])
            {
                i_is_unbeaten = false;
            }
        }
        if (i_is_unbeaten)
        {
            printf("%s\n", candidates[i]);
            return;
        }
    }
    return;
}

有什么建议吗?

c cs50
1个回答
0
投票

看来这一切都是由一个以main开头的变量引起的(原来的变量名是

main_id
,我改为
tmp_id
)。例如:

  • main_id
    :tigeman_test.c编译失败
  • tmp_id
    :tigeman_test.c编译OK
  • main_tmp_id
    :tigeman_test.c编译失败
  • tmp_id_main
    :tigeman_test.c编译OK
  • main_blah
    :tigeman_test.c编译失败
  • blah_main_blah
    :tigeman_test.c编译OK

我还没有找到一种方法将此作为错误提交给 CS50 团队,但我确实向他们标记了这篇文章。

© www.soinside.com 2019 - 2024. All rights reserved.