0
点赞
收藏
分享

微信扫一扫

C++案例——协助破案

题目

协助破案。假设已经查清,有 A、B、C、D、E 五个嫌疑人可能参与制造了一起抢劫银行案,但不知道其中哪几个是真正的案犯。不过,有确凿证据表明:

  1. 如果 A 参与了作案,则 B 一定也会参与。
  2. B 和 C 两人中只有一人参与了作案。
  3. C 和 D 要么都参与了作案,要么都没有参与。
  4. D 和 E 两个人中至少有一人参与作案。
  5. 如果 E 作案,则 A 和 D 一定参与作案。

分析

正规表达式

上述论断可以用数理逻辑中的正规表达式来表示:

  1. \(A \to B\)
  2. \(\left( {B \wedge \neg C} \right) \vee \left( {\neg B \wedge C} \right)\)
  3. \(\left( {C \wedge D} \right) \vee \left( {\neg C \wedge \neg D} \right)\)
  4. \(\left( {D \wedge E} \right) \vee \left( {\neg D \wedge E} \right) \vee \left( {D \wedge \neg E} \right)\)
  5. \(E \to \left( {A \wedge D} \right)\)

现在假设用 1(TRUE)表示作案,0(FALSE)表示未作案,则每个人的取值范围就是 \(\{0,1\}\) 。然后我们在 5 个人取值的所有可能的组合空间中进行搜索,同时满足这五条线索的一个组合就是本案的答案了。

C++ / C 逻辑表达式

于是上述正规表达式可以进一步表示为下列 C++ / C 逻辑表达式:

A==0 || (A==1 && B==1)
B+C == 1
C == D
D+E >= 1
E==0 || (E==1 && A==1 && D==1)

我们用另一个变量 ​​count​​ 来表示组合空间中某一个组合能够满足几条论断,如果出现了这样一个组合:它同时满足了这五条论断,那么它就是我们要找的组合。

实现

#include<stdio.h>
int main(void)
{
int A,B,C,D,E;
int count = 0;
for (A = 0; A < 2; A++)
{
for (B = 0; B < 2; B++)
{
for (C = 0; C < 2; C++)
{
for (D = 0; D < 2; D++)
{
for (E = 0; E < 2; E++)
{
count = 0; // 计数器清零
count += (A==0 || (A==1 && B==1));
count += (B+C == 1);
count += (C == D);
count += (D+E >= 1);
count += (E==0 || (E==1 && A==1 && D==1));
if (count == 5) // 找到一个满足所有条件的组合
{
goto finish;
}
}
}
}
}
}
finish:
printf("Suspect A is %s.\n", (A==1)?"a criminal":"not a criminal");
printf("Suspect B is %s.\n", (B==1)?"a criminal":"not a criminal");
printf("Suspect C is %s.\n", (C==1)?"a criminal":"not a criminal");
printf("Suspect D is %s.\n", (D==1)?"a criminal":"not a criminal");
printf("Suspect E is %s.\n", (E==1)?"a criminal":"not a criminal");
}

输出结果如下:

Suspect A is not a criminal.
Suspect B is not a criminal.
Suspect C is a criminal.
Suspect D is a criminal.
Suspect E is not a criminal.

摘自《​​高质量程序设计指南——C++/C语言 第3版​​》 P82

未经作者授权,禁止转载 THE END

举报

相关推荐

0 条评论