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.
CodePudding user response:
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;
}
CodePudding user response:
A flag is just a variable that lets you keep track of how things went, and adapt:
// 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?
bool found = false;
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))
{
found = true;
break;
}
}
}
if (!found)
{
locked[pairs[i].winner][pairs[i].loser] = true;
num_locked ;
}
}
}
Also note that there is no need to return
at the end of a void
function, it's okay to just fall off the end. :)
CodePudding user response:
One way is to add a test after the inner loop to check whether it was broken out of early. E.g.:
// 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 )
{
int j;
//has the loser won before?
for (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;
}
}
}
if (j < i)
{
continue;
}
locked[pairs[i].winner][pairs[i].loser] = true;
num_locked ;
}
return;
}
The scope of the j
variable needed to be changed so that it could be accessed outside the inner loop.