我是stackoverflow的新手,也是编程的新手。 我正在为CS50课程解决潮人问题。 https://cs50.harvard.edu/x/2020/psets/3/tideman/ 当我运行check50时,除以下内容外,所有内容都将检出:
:( lock_pairs如果创建循环则跳过最后一对 lock_pairs无法正确锁定所有非周期性对
这两个确实通过了测试: :) lock_pairs在没有周期时锁定所有对 :)如果创建一个循环,lock_pairs将跳过中间对
我找不到问题。我在这里想念什么?
这是我的代码:
// 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];
// Lock pairs into the candidate graph in order, without creating cycles
void lock_pairs(void)
{
// for every pair we need to check for a circle
for (int i = 0; i < pair_count; i++)
{
if (!circle_check(pairs[i].winner, pairs[i].loser))
{
//there's no circle: lock in pair
locked[pairs[i].winner][pairs[i].loser] = true;
}
}
}
// check pair for circles between winner and loser. Loser is first link
bool circle_check(int winner, int link)
{
// check if the loser already has connections
for (int n = 0; n < candidate_count; n++)
{
if (locked[link][n] == true)
{
// there's a link. if this ends in the winner, there's a circle
if (n == winner)
{
return true;
}
else
{
// there may still be a circle, check next connection
link = n;
circle_check(winner, link);
}
}
}
return false;
}
答案 0 :(得分:2)
关于您的代码/逻辑的一些观察结果:
执行circle_check
时,您正在link = n
中更改函数参数的值。优良作法是不要更改函数中作为参数传递的内容。另外,在这种情况下,您可以直接进行circle_check(winner, n)
。
您的circle_check
函数(显示)中,总是返回false。发生这种情况的原因是,当您从自身调用它时,实际上并没有使用它的返回值。假设递归调用返回 true :在“第一个”函数调用上,该行可以替换为:
else
{
link = n;
true;
}
而且,正如您可以想象的那样,它什么也不做,该函数继续正常执行,返回false。
如果您改为在函数调用前添加return
,则可以解决此问题。
但是还有第三点,您需要考虑:
locked[i][j]
矩阵的同一行上的链接进行多次检查。请允许我演示:假设您有一个5x5锁定矩阵,并且在第4行上,当前具有true(T)和false(F)的配置:
[F T T X F]
当函数线性搜索该行时,它将在上一个为true的lock [4] [1]处停止,并进行递归调用以查找链接。如果找到,它将返回 true ,并且您的lock_pairs
不会将true添加到locked
矩阵中。但是,如果找不到该怎么办?然后,与其去locked[4][2]
那里检查链接,不如返回false
,而这对将被锁定在lock_pairs
上。
例如,您可以通过在递归调用之后添加检查以解决它是否返回true或false来解决此问题。如果返回true,则表示存在链接,您不应将其添加到locked
中。另一方面,如果您输入错误,则表示没有链接,您可以继续在线上进行线性搜索。
else
语句可能类似于:
else
{
if (circle_check(winner,n)) // this way it only stops the search if a link was found
{
return true;
}
}