sta*_*15h 147 language-agnostic boolean-logic if-statement conditional-statements
我的问题是:
if (/* condition A */)
{
if(/* condition B */)
{
/* do action C */
}
else
/* ... */
}
else
{
/* do action C */
}
Run Code Online (Sandbox Code Playgroud)
是否可以只编写一次C代码而不是两次?
如何简化?
Que*_*onC 399
这些问题的第一步始终是制作逻辑表.
A | B | Result
-------------------
T | T | do action C
T | F | ...
F | T | do action C
F | F | do action C
Run Code Online (Sandbox Code Playgroud)
一旦你制作了表格,解决方案就很明确了.
if (A && !B) {
...
}
else {
do action C
}
Run Code Online (Sandbox Code Playgroud)
请注意,这种逻辑虽然较短,但对于未来的程序员来说可能难以维护.
Cod*_*ice 65
您有两种选择:
编写执行"动作C"的功能.
重新排列逻辑,以便您没有这么多嵌套的if语句.问问自己什么条件导致"行动C"发生.它看起来像是在"条件B"为真或"条件A"为假时发生.我们可以把它写成"NOT A OR B".将其转换为C代码,我们得到
if (!A || B) {
action C
} else {
...
}
Run Code Online (Sandbox Code Playgroud)为了更多地了解这些表达式,我建议谷歌搜索"布尔代数","谓词逻辑"和"谓词演算".这些都是深刻的数学主题.您不需要全部学习,只需要了解基础知识.
您还应该了解"短路评估".因此,表达式的顺序对于精确复制原始逻辑非常重要.虽然B || !A
在逻辑上是等价的,但是当条件B
为真时,使用它作为条件将执行"action C",而不管其值是多少A
.
Cin*_*out 15
您可以像这样简化语句:
if ((A && B) || (!A)) // or simplified to (!A || B) as suggested in comments
{
do C
}
Run Code Online (Sandbox Code Playgroud)
否则将'C'的代码放在一个单独的函数中并调用它:
DoActionC()
{
....
// code for Action C
}
if (condition A)
{
if(condition B)
{
DoActionC(); // call the function
}
else
...
}
else
{
DoActionC(); // call the function
}
Run Code Online (Sandbox Code Playgroud)
Aar*_*ach 14
在具有模式匹配的语言中,您可以以更直接反映QuestionC答案中的真值表的方式表达解决方案.
match (a,b) with
| (true,false) -> ...
| _ -> action c
Run Code Online (Sandbox Code Playgroud)
如果您不熟悉语法,则每个模式都由|表示 后跟要与(a,b)匹配的值,并且下划线用作通配符以表示"任何其他值".由于我们想要做除动作c之外的其他事情的唯一情况是当a为真且b为假时,我们明确地将这些值表示为第一个模式(true,false),然后在那种情况下做任何应该做的事情.在所有其他情况下,我们都会陷入"通配符"模式并执行操作c.
jam*_*lin 10
问题陈述:
如果条件A匹配,则需要匹配条件B以执行动作C.
描述暗示:A暗示B,等同于!A || B
(如其他答案中所述)的逻辑命题:
bool implies(bool p, bool q) { return !p || q; }
if (implies(/* condition A */,
/* condition B */))
{
/* do action C */
}
Run Code Online (Sandbox Code Playgroud)
呃,这也让我感到高兴,但正如Code-Apprentice指出的那样,我们保证需要do action C
或运行嵌套else
块,因此代码可以简化为:
if (not condition A or condition B) {
do action C
} else {
...
}
Run Code Online (Sandbox Code Playgroud)
这就是我们如何击中3个案例:
do action C
在你的问题的逻辑要求condition A
,并condition B
为true
-在这样的逻辑,如果我们达到2 次的术语if
语句来那么我们就知道condition A
是true
这样,所有我们需要评估的是,condition B
是true
else
在你的问题的逻辑-阻塞要求condition A
是true
和condition B
是false
-我们能够达到的唯一方法else
在这种逻辑-阻塞是,如果condition A
是true
和condition B
人false
else
你的问题的逻辑要求-块condition A
是false
-在这样的逻辑,如果condition A
是假的,我们也do action C
Code-Apprentice的道具让我在这里理顺.我建议接受他的答案,因为他没有编辑就正确地提出了答案:/
尽管已经有了很好的答案,但我认为这种方法对于那些刚接触布尔代数然后评估真值表的人来说可能更直观.
你要做的第一件事就是看,你想在哪些条件下执行C.这就是这种情况(a & b)
.当时!a
.所以你有(a & b) | !a
.
如果你想最小化你可以继续下去.就像在"普通"算术中一样,你可以相乘.
(a & b) | !a = (a | !a) & (b | !a)
.a | !a总是如此,所以你可以把它划掉,这样你就可以得到最小化的结果:b | !a
.如果顺序有所不同,因为你只想检查b!a是否为真(例如,当a是空指针检查而b是对指针的操作,如@LordFarquaad在他的评论中指出的那样),你可能会想要切换两个.
另一种情况(/*...*/)将在c未执行时始终执行,因此我们可以将其放在else的情况下.
另外值得一提的是,将动作c放入方法可能有意义.
这给我们留下了以下代码:
if (!A || B)
{
doActionC() // execute method which does action C
}
else
{
/* ... */ // what ever happens here, you might want to put it into a method, too.
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您还可以使用更多操作数来最小化术语,这些操作数很快会因真值表而变得难看 另一个好方法是卡诺图.但我现在不会深入研究这个问题.
在逻辑概念中,您可以按如下方式解决此问题:
f = ab +!a
f =?
作为一个经过验证的问题,这导致了f = !a + b
.有一些方法可以证明问题,如真值表,卡诺图等.
所以在基于C语言中你可以使用如下:
if(!a || b)
{
// Do action C
}
Run Code Online (Sandbox Code Playgroud)
PS:卡诺图也用于更复杂的一系列条件.这是一种简化布尔代数表达式的方法.