You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中如何跳出内层嵌套循环并继续外层循环(CS50 Tideman问题)

CS50 Tideman问题:跳出内层循环并跳过外层循环后续代码的解决方案

我首次在网站上发布编程问题,若表述有不当之处敬请谅解,欢迎给出建设性反馈。我正在解决CS50中的Tideman问题。

我无法找到一种既能跳出内层嵌套循环,又能继续执行外层循环的方法。具体来说,当is_cycle返回true时,需要跳过当前外层循环迭代中的以下代码:

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

我已查阅相关资料,有人提到使用goto但多数人认为这是不良编程习惯;还有人建议创建独立函数并使用return,但我需要外层循环继续而非终止;另外有人提到使用flags,但我仍不清楚如何应用。以下是我的代码:

// 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;
}

解决方案:使用标志位(Flag)控制流程

最清晰且符合规范的做法是引入一个布尔标志位,用来标记当前外层循环迭代是否需要跳过后续的锁定代码。具体实现如下:

// Lock pairs into the candidate graph in order, without creating cycles
void lock_pairs(void)
{
    int num_locked = 0;
    for (int i = 0; i < pair_count; i++)
    {
        bool should_lock = true; // 初始化标志位,默认允许锁定当前配对
        // 检查当前配对的失败者是否曾获胜过,以及是否会形成循环
        for (int j = 0; j < i; j++)
        {
            if (pairs[i].loser == pairs[j].winner)
            {
                if (is_cycle(pairs[i], pairs[j], num_locked))
                {
                    should_lock = false; // 标记为不允许锁定
                    break; // 跳出内层循环
                }
            }
        }
        // 根据标志位决定是否执行锁定操作
        if (should_lock)
        {
            locked[pairs[i].winner][pairs[i].loser] = true;
            num_locked++;
        }
    }
    return;
}

补充说明

  • 标志位的方式既避免了goto的争议,也不需要拆分函数就能保持外层循环继续执行,代码可读性更高。
  • 注意:你的原代码内层循环仅检查了pairs[i].loser == pairs[j].winner的场景,实际判断循环可能需要更全面的路径遍历,这部分逻辑取决于你is_cycle函数的实现是否完善。

内容的提问来源于stack exchange,提问作者user20633421

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:30:54