CS50 tideman-:(如果创建循环,lock_pairs将跳过最后一对

时间:2020-08-01 11:50:38

标签: c cs50

我是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;
}

1 个答案:

答案 0 :(得分:2)

关于您的代码/逻辑的一些观察结果:

  1. 执行circle_check时,您正在link = n中更改函数参数的值。优良作法是不要更改函数中作为参数传递的内容。另外,在这种情况下,您可以直接进行circle_check(winner, n)

  2. 您的circle_check函数(显示)中,总是返回false。发生这种情况的原因是,当您从自身调用它时,实际上并没有使用它的返回值。假设递归调用返回 true :在“第一个”函数调用上,该行可以替换为:

else
{
  link = n;
  true;
}

而且,正如您可以想象的那样,它什么也不做,该函数继续正常执行,返回false。

如果您改为在函数调用前添加return,则可以解决此问题。

但是还有第三点,您需要考虑:

  1. 您的函数未考虑对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;
  }
}