Search code examples
cnested-loopscs50breakcontinue

In C, how do i break out of a nested inner loop but continue the outer loop?


This is my first time posting a coding question on any website, so apologies if i dont do a great job. Constructive feedback is very welcome. I am working on the tideman problem in cs50, if that is meaningful to anyone.

I cant figure out a way to break out of the inner nested loop but continue the outer loop. As in, if is_cycle is true, the lines:

locked[pairs[i].winner][pairs[i].loser] = true;
num_locked++;

need to be skipped for that current iteration of the outer loop.

Thank you so much.

// Lock pairs into the candidate graph in order, without creating cycles
void lock_pairs(void)
{
    int num_locked = 0;
    //loop through pairs
        //has loser won before?
            //if no, lock the pair
            //if yes, call is_cycle on pair. if its not a cycle lock the pair
    for (int i = 0; i < pair_count; i++)
    {
        //has the loser won before?
        for (int j = 0; j < i; j++)
        {
            if (pairs[i].loser == pairs[j].winner)
            {
                //if the loser has won before and it creates a cycle, break the inner loop, continue outer
                if (is_cycle(pairs[i], pairs[j], num_locked))
                {
                    break;
                }
            }
        }
        //this is incorrect this will lock the pair each time
        locked[pairs[i].winner][pairs[i].loser] = true;
        num_locked++;
    }

    return;
}

I have tried searching through stack overflow. Some mentioned a goto function but most people said that is bad programming. someone else mentioned creating a separate function and using return statements but i need that outer loop to continue, not stop. And one other answer suggested using flags, which after more searching i still dont get how that could help.


Solution

  • Although goto should generally be avoided if there is a better alternative, for breaking out of a nested loop or continuing an outer loop, I do recommend using goto, as there is no clearly better alternative.

    // Lock pairs into the candidate graph in order, without creating cycles
    void lock_pairs(void)
    {
        int num_locked = 0;
        //loop through pairs
            //has loser won before?
                //if no, lock the pair
                //if yes, call is_cycle on pair. if its not a cycle lock the pair
        for (int i = 0; i < pair_count; i++)
        {
            //has the loser won before?
            for (int j = 0; j < i; j++)
            {
                if (pairs[i].loser == pairs[j].winner)
                {
                    //if the loser has won before and it creates a cycle, break the inner loop, continue outer
                    if (is_cycle(pairs[i], pairs[j], num_locked))
                    {
                        goto continue_outer_loop;
                    }
                }
            }
            //this is incorrect this will lock the pair each time
            locked[pairs[i].winner][pairs[i].loser] = true;
            num_locked++;
    
        continue_outer_loop:
            continue;
        }
    
        return;
    }