C 语言 4 位可能的变体,但有例外

C languange 4 digit possible variations with exception

提问人:Mārtiņš Strazdiņš 提问时间:1/17/2019 最后编辑:BlazeMārtiņš Strazdiņš 更新时间:9/20/2019 访问量:87

问:

所以我有一个家庭作业,但我无法理解为什么这段代码不起作用。

问题听起来是这样的:

制作一个代码来检查 4 位数字的所有可能变体,但数字中没有 3 位相同的数字。(我希望这是有道理的)

我的代码:

#include<stdio.h>


int main ()
{
        int i;
        char a,b,c,d;

        for (i=0; i<9999; i++)
        {
                a = i/1000;
                b = i/100%10;
                c = i/10%10;
                d = i%10;

                if (a==b==c)    {i++;}
                else if (b==c==d)       {i++;}
                else if (c==d==a)       {i++;}
                else if (d==a==b)       {i++;}
                else if (a==b==c==d)    {i++;}

                else
                {
                        printf("%d,%d,%d,%d\n", a,b,c,d);
                }
        }
}

我希望它打印出这样的东西:

0,0,1,1
0,0,1,2
0,0,1,3
...
0,1,0,9
0,1,1,0
0,1,1,2
...
9,9,8,8

相反,它打印:

0,1,2,2
0,1,3,3
0,1,4,4
0,1,5,5
0,1,6,6
...
0,8,6,6
0,8,7,7
0,8,8,8
0,8,9,9
0,9,2,2
...
9,9,9,8
c 平等

评论

0赞 Some programmer dude 1/17/2019
该表达式实际上等于 ,这意味着您正在与 的布尔结果进行比较a==b==ca==(b==c)ab == c
0赞 pmg 1/17/2019
@Someprogrammerdude:或者......https://ideone.com/sRY0Gbprintf("0==4==3 is %s\n", 0==4==3?"true":"false");printf("0==(4==3) is %s\n", 0==(4==3)?"true":"false");
0赞 Some programmer dude 1/17/2019
@pmg该死的,弄错了关联性。它。(a == b) == c
0赞 pmg 1/17/2019
@Someprogrammerdude:也产生一个结果;或:)b == cint01

答:

1赞 Olf 1/17/2019 #1

你不能像这样使用多个等式。您必须分别使用 和 条件(例如)。a==b && b==c

评论

1赞 Bathsheba 1/17/2019
“你不能使用多重等式”——是的,你可以,只是用另一种方式写它有不同的含义。
3赞 Blaze 1/17/2019 #2

这些比较存在问题:

 if (a==b==c)

这并不能找出 是否 和 都是一样的。的结果是 或 ,然后将其与第三个数字进行比较。因此,根据示例,如果所有三个数字都是 ,则变成 ,即 ,因此不取 。更重要的是,您对诸如 .abc==0199==9==91==90if9==9==1

相反,您需要的是

if ((a==b) && (a==c))

现在你检查是否等于 ,当它等于时,你用 检查它,如果它们都相同,则取 。abcif

当然,对于其他比较也是如此,所以而不是你想要的else if (a==b==c==d)else if ((a==b) && (a==c) && (a==d))

评论

0赞 Mārtiņš Strazdiņš 1/17/2019
多谢!解决了我的问题!
2赞 ad absurdum 1/17/2019 #3

正如其他答案所指出的,您无法在 C 中链接比较运算符并获得预期的结果。使用逻辑运算符组合比较。使用以避免所有语句可能会更清楚。||else

发布的代码还有另一个重大问题:每当发现失败的编号时,代码就会递增。但随后又被循环递增。这会导致跳过失败号码后的号码,因此找不到一些所需的号码。例如,应该失败,后面的数字应该通过,但这个数字被发布的代码跳过(在比较更正之后),下一个数字要检查。相反,只需使用:iifor322232233224continue

if ((a == b && a == c) ||
    (b == c && b == d) ||
    (c == d && c == a) ||
    (d == a && d == b) ||
    (a == b && a == c && a == d)) {
    continue;
} else {
    printf("%d,%d,%d,%d\n", a,b,c,d);
}

评论

0赞 JeremyP 1/17/2019
最好只是否定测试并将 放入块中,从而消除printfifcontinue
0赞 ad absurdum 1/17/2019
@JeremyP -- 我确信有更好的方法来表达这一点,但我想接近 OP 的逻辑,并专注于对比较运算符用法的更正和错误的额外增量。也就是说,我编写的修改后的代码似乎很清楚,我不确定使用否定会增加这种清晰度。i