首先,我是电子系的,学硬件,没有学离散数学,所以不知道这部分内容是不是离散
数学里面的东西 .... 我们学习《数字逻辑电路》的时候学了布尔代数的基本定律,逻辑
表达式的化简,卡诺图的化简等内容。
《中学生C语言入门演练100例》李学武编著,清华大学出版社
不要被题目骗了,里面的部分例子可不简单,至少要非常熟悉C语言才能很好的做出来....
其中p73有这么一题:
A B C D E 五个学生当中的部分学生参加了计算机竞赛,根据下面的条件判断那些人参加了:
1)A 参加时,B也参加
2)B 和 C 只有一个人参加
3)C 和 D 或者都参加,或者都不参加
4)D 和 E 当中至少有一个人参加
5)如果 E 参加,那么 A 和 D 也都参加
记得这像是初中的数学奥赛题目,考逻辑思维能力的。当然了,我没有那种思维......今天
主要是谈谈怎么用C语言来做这种逻辑题。
根据数字逻辑电路上面学的,怎么得出逻辑表达式,可以先列真值表,然后写出逻辑表达式,
最后化简。
以下表达式中,1表示参加,0表示不参加
第一个条件 “A 参加时,B也参加”
真值表
A B
1 1
0 x
其中 x 代表“无关项”,也就是它的取值可0可1,并不影响最终的逻辑。所以这个真值表的意思
是,A去的话B也去,A不去的话,B可能去,也可能不去。无关项的逻辑为“1”,表示肯定成立。
所以这里的逻辑表达式为
L = (A && B) || (!A && 1) = (A && B) || !A
其中化简的依据是 A && 1 = A,布尔代数的定量
第二个条件 “B 和 C 只有一个人参加”
真值表
B C
0 1
1 0
当B不参加的话C参加,当B参加的话C不参加,这就实现了逻辑 B C 同时只有一个人参加的条件
所以逻辑表达式L应该就是这两种情况其中的任何一种,也就是“或”逻辑
L = (B && !C) || (!B && C)
第三个条件 “C 和 D 或者都参加,或者都不参加”
真值表
C D
0 0
1 1
这里也是顺理成章的
L = (!C && !D) || (C && D)
第四个条件 “D 和 E 当中至少有一个人参加”
真值表
D E
0 1
1 X
这里的逻辑是,当D不参加,E肯定要参加,才能满足逻辑,如果D参加了,那么E可以参加,也可以
不参加,所以这里是无关项。
L = (!D && E) || (D && 1) = D || E
这里是做了化简,根据吸收率 L = D+!DE = D+E,通常化到最简单的逻辑比较大比较好写。
第五个条件 “如果 E 参加,那么 A 和 D 也都参加”
真值表
E A D
0 x x
1 1 1
如果E不参加,那么A D就是无关项,可能参加,也可能不参加。所以
L = (E && A && D) || (!E && 1 && 1) = !E || (A && D)
程序的几点解释:
根据上面分析的5个条件,A B C D E分别取0和1,如果某一组数据同时满足这5个条件的话,那么
输出,这个就是答案了。
虽然按照这个逻辑分析出来的表达式和书本上有点出入,特别是第二和第三个,但是最后答案却是相
同的,可见逻辑是正确的。
为什么要循环32次?其实如果将 A B C D E 看成是二进制的5个bit的话,那么就是
0000 ~ 11111 之间的取值,也就是十进制的0到31了,这样就可以省去5层循环嵌套了。有时可以看出
数学,电路,程序,逻辑之间,其实原理是共同的......
最后的答案是 ABCDE:00110
#include <stdio.h> #include <stdlib.h> #include <string.h>
int main(int argc,char *argv[]) { int i; int A,B,C,D,E;
for (i=0;i<32;i++) { A=i&1,B=(i>>1)&1,C=(i>>2)&1,D=(i>>3)&1,E=(i>>4)&1;
if ( ((A && B) || !A) && ((B && !C) || (!B && C)) && ((!C && !D) || (C && D)) && (D || E) && (!E || (A && D)) ) printf("\nfind ABCDE : %d %d %d %d %d",A,B,C,D,E); }
return 0; }
|
阅读(3096) | 评论(3) | 转发(1) |