CS50 tideman - :( lock_pairs skips final pair if it creates cycle

╄→尐↘猪︶ㄣ 提交于 2021-01-05 06:08:48

问题


I'm new to stackoverflow and pretty new to programming. I'm working on the tideman problem for the CS50 course. https://cs50.harvard.edu/x/2020/psets/3/tideman/ When I run check50 everything checks out except for one:

:( lock_pairs skips final pair if it creates cycle lock_pairs did not correctly lock all non-cyclical pairs

These two do pass the test: :) lock_pairs locks all pairs when no cycles :) lock_pairs skips middle pair if it creates a cycle

I can't find the problem. What am I missing here?

This is my code:

// 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:


A few observations about your code/logic:

  1. You are altering the value of your function argument in circle_check when you do link = n. It's good practice to not alter what's passed in as an argument in a function. Plus, on this specific case, you could do circle_check(winner, n) directly.

  2. Your circle_check function, as it is presented, always returns false. That happens because when you call it from itself, you're not actually using it's return for anything. Let's say that recursive call returns true: On the 'first' function call, the line could be replaced by:

else
{
  link = n;
  true;
}

And, as you can imagine, that does nothing and the function continues it's execution normally, returning false.

If you, instead, add a return in front of the function call, you solve this problem.

But then there's also a 3rd point, that you need to consider:

  1. Your function does not account for multiple checks for links on the same line of the locked[i][j] matrix. Allow me to demonstrate:

Imagine you have a 5x5 locked matrix, and on line 4 you currently have this disposition of true (T) and false (F):

[ F T T X F ]

When your function linear searches through the line, it's going to stop on locked[4][1], the first true, and do the recursive call to find a link. If it does find, it's going to return true and your lock_pairs is not going to add true to the locked matrix. But, what if it doesn't find? Then, instead of going to locked[4][2] to check for links there, it's just going to return false and the pair is going to be locked on lock_pairs.

You could solve this, for example, by adding a check after the recursive call, to see if it was returned true or false there. If true is returned, it means there's a link and you should NOT add the pair to locked. On the other hand, if you get false, it means there's no link and you can continue the linear search on the line.

The else statement could look something like:

else
{
  if (circle_check(winner,n)) // this way it only stops the search if a link was found
  {
    return true;
  }
}


来源:https://stackoverflow.com/questions/63204878/cs50-tideman-lock-pairs-skips-final-pair-if-it-creates-cycle

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!