【发布时间】:2020-06-03 06:53:31
【问题描述】:
现在我正在尝试检查我所做的每个功能。 我已经完成了对 vote 和 record_preference 函数的检查。它奏效了。 现在,我对尝试使用合并排序的排序功能感到震惊。 我在过去的问题中一直在使用此合并功能,但是,当我尝试使用它时。 它向我展示了“分段错误”。 这是我的终端[picture 1],当我尝试插入像这张图片[picture 2] 这样的选票时。 如您所见,“排序前”出现了,但“排序后”没有出现。反而出现了“分段错误”。
ps。 score_winner 是一个变量,我使用它就像分数标签一样按升序对对进行排序。我认为终端应该看起来像(如下)。
before sort :
pair 0 :7 alice bob
pair 1 :6 charlie alice
pair 2 :5 bob charlie
after sort :
pair 0 :5 bob charlie
pair 1 :6 charlie alice
pair 2 :7 alice bob
我的代码[merge函数在最里面]
#include <cs50.h>
#include <stdio.h>
#include <string.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
void merge(int left, int mid, int right);
void merge_sort(int left, int right);
bool vote(int rank, string name, int ranks[]);
void record_preferences(int ranks[]);
void add_pairs(void);
void sort_pairs(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();
printf("%i \n", pair_count);
printf("before sort : \n");
for(int i=0;i<pair_count;i++)
{
printf("pair %i :", i);
printf("%i ", preferences[pairs[i].winner][pairs[i].loser]); //score of winner
printf("%s ", candidates[pairs[i].winner]);
printf("%s ", candidates[pairs[i].loser]);
printf("\n");
}
printf("\n");
merge_sort(0, pair_count - 1);
printf("after sort : ");
for(int i=0;i<pair_count;i++)
{
printf("pair %i :", i);
printf("%i ", preferences[pairs[i].winner][pairs[i].loser]); //score of winner
printf("%s ", candidates[pairs[i].winner]);
printf("%s ", candidates[pairs[i].loser]);
printf("\n");
}
printf("\n");
return 0;
}
// Update ranks given a new vote
bool vote(int rank, string name, int ranks[])
{
// TODO
string name1[candidate_count];
for (int i = 0; i < candidate_count; i++)
{
name1[i] = candidates[i];
}
int sum = 0;
for (int j = 0; j < candidate_count; j++)
{
if (strcmp(name, name1[j]) == 0)
{
sum = sum + 1;
ranks[rank] = j;
}
else
{
sum = sum + 0;
}
}
if (sum == 1)
{
return true;
}
else
{
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++)
{
if (i < j)
{
preferences[ranks[i]][ranks[j]] = preferences[ranks[i]][ranks[j]] + 1;
}
else
{
preferences[ranks[i]][ranks[j]] = preferences[ranks[i]][ranks[j]] + 0;
}
}
}
return;
}
// Record pairs of candidates where one is preferred over the other
void add_pairs(void)
{
// TODO
for (int i = 0; i < candidate_count; i++)
{
for (int j = 0; j < candidate_count; j++)
{
if (i < j)
{
if (preferences[i][j] < preferences[j][i])
{
pairs[pair_count].winner = j;
pairs[pair_count].loser = i;
pair_count = pair_count + 1;
}
else if (preferences[i][j] > preferences[j][i])
{
pairs[pair_count].winner = i;
pairs[pair_count].loser = j;
pair_count = pair_count + 1;
}
else
{
pair_count = pair_count + 0;
}
}
}
}
return;
}
// Sort pairs in decreasing order by strength of victory
void sort_pairs(void)
{
// TODO
merge_sort(0, pair_count - 1);
}
void merge(int left, int mid, int right)
{
int len1 = mid - left + 1;
int len2 = right - mid;
int i;
int index1 = 0, index2 = 0;
// create temp array
int score_winner[MAX];
for (i = 0; i < pair_count; i++)
{
score_winner[i] = preferences[pairs[i].winner][pairs[i].loser];
}
int left_array[len1];
int right_array[len2];
int str_win_left_array[len1];
int str_win_right_array[len2];
int str_los_left_array[len1];
int str_los_right_array[len2];
//take array to temp array
for (i = 0; i < len1; i++)
{
left_array[i] = score_winner[left + i];
str_win_left_array[i] = pairs[left + i].winner;
str_los_left_array[i] = pairs[left + i].loser;
}
for (i = 0; i < len2; i++)
{
right_array[i] = score_winner[mid + 1 + i];
str_win_left_array[i] = pairs[mid + 1 + i].winner;
str_los_left_array[i] = pairs[mid + 1 + i].loser;
}
i = left;
while (index1 < len1 && index2 < len2)
{
if (left_array[index1] < right_array[index2])
{
score_winner[i] = left_array[index1];
pairs[i].winner = str_win_left_array[index1];
pairs[i].loser = str_los_left_array[index1];
index1++;
}
else
{
score_winner[i] = right_array[index2];
pairs[i].winner = str_win_right_array[index2];
pairs[i].loser = str_los_right_array[index2];
index2++;
}
i++;
}
// check for other one
while (index1 < len1)
{
score_winner[i] = left_array[index1];
pairs[i].winner = str_win_left_array[index1];
pairs[i].loser = str_los_left_array[index1];
i++;
index1++;
}
while (index2 < len2)
{
score_winner[i] = right_array[index2];
pairs[i].winner = str_win_right_array[index2];
pairs[i].loser = str_los_right_array[index2];
i++;
index2++;
}
}
void merge_sort(int left, int right)
{
int mid;
int i;
if (left < right)
{
mid = (left + right) / 2;
merge_sort(left, mid);
merge_sort(mid + 1, right);
merge(left, mid, right);
}
}
【问题讨论】:
-
在不相关的说明中,您不需要
typedef用于 C++ 中的结构。struct就像class一样,因此结构标记名称可以用作类型,而无需typedef。另一方面,我可以看到代码中实际上没有任何东西使它成为“C++”。对我来说,这一切都像是普通的 C(当你需要这样的typedef时)。 -
至于你的问题,你有没有试过在调试器中运行你的程序?什么时候在你的程序中发生崩溃?那时所有涉及的变量的值是多少?
-
最后请花点时间阅读the help pages,阅读SO tour,阅读How to Ask,以及this question checklist。另外请学习如何创建minimal reproducible example,重点是minimal部分。
-
CS50 是一门 C 课程。 C 和 C++ 是非常不同的语言。