【问题标题】:C++ Problem: 'break' within nested for loops not working as expected?C++ 问题:嵌套 for 循环中的“中断”不能按预期工作?
【发布时间】:2019-07-31 07:35:50
【问题描述】:

我正在尝试编写一个程序来查找具有以下条件的特定 4 位数字:

  • 所有四个数字都不同。
  • 千位数字是十位数字的三倍。
  • 数字是奇数。
  • 数字之和为 27。

我正在努力编写这个程序。我尝试嵌套 for 循环迭代每个数字,直到满足条件(当 break 终止循环时),如下所示:

int a = 1;
int b = 1;
int c = 1;
int d = 1;

for (a = 1; a < 9; a++) {
    for (b = 1; b < 9; b++) {
        for (c = 1; c < 9; c++) {
            for (d = 1; d < 9; d++) {

                if (a + b + c + d == 27 && a == 3 * c && a != b && a != c
                && a != d && b!= c && b != d && c != d && d % 2 != 0) {
                    break;
                }
            }
        }
    }
}

我希望数字 a、b、c、d 为我提供满足上述 if 语句中的所有条件并因此中断的数字。相反,abcd 始终为 9999。为什么会发生这种情况?我怎么会误用break?

【问题讨论】:

  • 你的条件是错误的,你永远不会在 4 位数字之外建立一个数字。
  • 创建一个包含这个for循环的函数并使用return而不是break
  • 我建议将你的 if 语句分解成嵌套的 if 语句:if(condition1){ if(condition2){ if(condition3){. . .} } },以便调试更容易。
  • 您只考虑了 10 个可能数字中的 8 个

标签: c++


【解决方案1】:

break 只会跳出最里面的循环。因此,当您达到您的条件时,您只需进入 c 值的下一次迭代。

【讨论】:

  • 非常感谢。我会把它放在最外面的循环中。
【解决方案2】:
#include<stdio.h>

int findNum();

int main()
{
    int num;
    num = findNum();
    printf("%d is the required number.\n\n",num);
    return 0;
}

int findNum()
{
    int a, b, c, d;
    for (a = 1; a <= 9; a++)
    {
        for (b = 0; b <= 9; b++)
        {
            for (c = 0; c <= 9; c++)
            {
                for (d = 0; d <= 9; d++)
                {
                    if (a+b+c+d==27 && a==(3*c) && a!=b && a!=c && a!=d && b!=c && b!=d && c!=d && (d%2)!=0)
                    {
                        return (1000*a)+(100*b)+(10*c)+d;
                    }
                }
            }
        }
    }
}

【讨论】:

  • 没有解释?
【解决方案3】:

如果你想退出所有循环,Break 只会中断内部循环,你可以使用 return 或使用变量 say flag

int a = 1;
int b = 1;
int c = 1;
int d = 1;
int flag=0;
for (a = 1; a < 9; a++) {
    for (b = 1; b < 9; b++) {
        for (c = 1; c < 9; c++) {
            for (d = 1; d < 9; d++) {

if (a + b + c + d == 27 && a == 3 * c && a != b && a != c
&& a != d && b!= c && b != d && c != d && d % 2 != 0) {
flag=1;
                    break;//breaks d loop
}
if(flag==1)
break;//breaks c loop
}
if(flag==1)
break;//breaks b loop
}
if(flag==1)
break;//breaks a loop
}

这是一种不好的做法,但会给出正确的输出。我更喜欢使用 return 语句,或者你可以使用 goto 语句跳出循环

【讨论】:

    【解决方案4】:

    我建议将计算放入一个函数中,当return满足条件时退出函数,并返回值。

    我的改进建议

    • 在您的原始代码中,当必须测试 0 到 9 时,您只测试 1 到 8 的值。
    • 对于a,只需测试 3、6 和 9。
    • c 可以从 a 派生,因此您可以消除 for 循环测试 c 值。
    • 仅在d 循环中循环奇数。
    • 切换 bd 循环,以减少外循环中的代码运行次数。
    • 分隔 if 语句以便于阅读,您可以在调试器中逐行逐行检查条件,并且可以更容易地指定在哪个条件下产生错误的错误。
    • a 永远不会等于 c,因此无需检查。
    • 检查 ac 不等于 d 就在 d 循环内。
    • 在添加数字并检查它们是否等于 27 之前检查 b 不等于其他数字。
    #include <iostream>
    
    using namespace std;
    
    int find_number(){
        int a, b, c, d, result;
    
        for(a = 3; a <= 9; a += 3){ // Only runs 3 times
            c = a/3;
            for(d = 1; d <= 9; d += 2){
                if(a != d){
                if(c != d){
                    for(b = 0; b <= 9; b++){
                        if(b != d){
                        if(b != a){
                        if(b != c){
                        if(a + b + c + d == 27){ 
                            result = a*1000 + b*100 + c*10 + d;
                            return result;
                        } // end ifs
                        }
                        }
                        }
                    } // end for
                } // end ifs
                }
            } // end for
        } // end for
    
    } // end find_number()
    
    int main()
    {
        cout << find_number() << endl;
    
        return 0;
    } // end main()
    

    【讨论】:

    • “将 if 语句分开,以便于阅读。” 呃,这很主观。 (也没有缩进……因此,您甚至不得不将 cmets 放在右大括号上。)
    • 你是对的,这是主观的,但如果它们都在一条线上,你就不能逐步完成条件(这可能是我应该在答案中包含的内容......我通常把cmets 放在闭括号中,因为它们总是让我感到困惑。我认为如果它们以传统方式缩进看起来会更令人困惑。如果您认为这很糟糕,我会更正它,因为您在此站点上拥有资历。
    • 不,如果认为您的方式更好,请不要编辑它。即使我有更多虚构的互联网点,也不一定能让我正确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多