抽象思维和逻辑思维是程序设计的基础[转]

时间:2021-07-28 13:54:40

★ 会写关系表达式和逻辑表达式对编程是至关重要的,这一步上不去,后面会步步上不去

★ 我们强调理性思维和理性实践,强化上机动手动脑,编出来调不出来,不算真本事;编出的程序正确与否,要经过上机实践的检验

★ 没有实践就没有提高能力的土壤


逻辑思维在程序设计中十分重要,应该重点加以介绍。为此,我们设计了“逻辑问题及其解法”一节。为了一开始就能吸引听众,首先给出一个疑案分析的例题。

[例题] 某地刑侦大队对涉及6个嫌疑人的一桩疑案进行分析:

(1)A、B至少有 1 人作案;

(2)A、E、F 3 人中至少有2人参与作案;

(3)A、D不可能是同案犯;

(4)B、C或同时作案,或都与本案无关;

(5)C、D中有且仅有 1 人作案;

(6)如果D没有参与作案,则E也不可能参与作案。

试编一程序,将作案人找出来。

我们借用上述这个题目,向学生讲解逻辑运算符、逻辑表达式和涉及逻辑问题的解题思路。

在介绍逻辑与、逻辑或和逻辑非三个运算符之后,立刻就用它们来写逻辑表达式,这里结合疑案分析中的6句话,利用真值表写出6个逻辑表达式:

CC1=(A||B); // A和B至少有1人作案

CC2=!(A&&D);//A和D不可能是同案犯

CC3=(A&&E) || (A&&F) || (E&&F);//A、E、F中至少有2人涉嫌作案

CC4=(B&&C) || (!B&&!C);//B和C或同时作案,或都与本案无关

CC5=(C&&!D)||(D&&!C);//C、D中有且仅有1人作案

CC6=D || !E;//如果D没有参与作案,则E也不可能参与作案

逻辑表达式的取值非“真”即“假”。在上述6个式子中,赋值号“=”右边的是逻辑表达式,左边的CC1、CC2、…CC6是布尔类型的变量,其值非0即1,也可以用整型数来定义。

将疑案分析中的6句话写成6个逻辑表达式是一种基本功,这是解决这一类问题的前提条件,学会这部分内容十分重要。

我们将案情分析的这6个表达式归纳成一条,称之为破案综合判断条件CC:

CC=CC1&&CC2&&CC3& &CC4&&CC5&&CC6

从上式看出,只有当CC1、CC2、…CC6每一条都为“真”,则CC才为“真”。从CC1到CC6是与A、B、C、D、E、F 中6 个人的所作所为有关,必须将6个人干过的事(作案与否)代至公式中去看是否能使CC为“真”,这当然又想到了要用“枚举”法。

在讲堂上,定义了6个整形变量:A、B、C、D、E、F,让变量取值为0表示不是作案人,为1表示是作案人。每个人都有两种可能:“是”或者“不是”,6个人作为整体,存在26种可能。按A、B、C、D、E、F的顺序,整体取值从000000,000001,…,111111,给出了一张64种可能的表,见表1。

实现这张表是枚举的一个基础,要用到6重循环,循环控制变量分别是A、B、C、D、E、F,初值均为0,终值均为1。A循环处在最外层,F循环处在最里层,形成一个套一个的嵌套关系。接着就可以讲多重循环的语句如何写,程序框图怎样画等问题。先让学生上机实现将000000到111111的表打出来,借此巩固多重循环的概念及编写方法,也是为了给进一步解析疑案搭一个台阶。为此,建议写一条输出语句:

cout << A << B << C << D <<E<<F<< endl;         (1)

把它当作6重循环的循环体,就可以模拟产生从000000到111111的64种可能情况。

经过上述的讲解之后,解决了枚举A、B、C、D、E、F分别取值0或1的组合问题。要寻找哪些人是罪犯,就要改造(1)式,即让循环体包含如下两部分内容:

1.根据ABCDEF的值,计算 CC1到CC6的值

CC1=(A||B); // A和B至少有1人作案

CC2=!(A&&D);//A和D不可能是同案犯

CC3=(A&&E) || (A&&F) || (E&&F);//A、E、F中至少有2人涉嫌作案

CC4=(B&&C) || (!B&&!C);//B和C或同时作案,或都与本案无关

CC5=(C&&!D)||(D&&!C);//C、D中有且仅有1人作案

CC6=D || !E;//如果D没有参与作案,则E也不可能参与作案

2.分支结构,其中条件语句是

if(CC1+CC2+CC3+CC4 +CC5+CC6==6)

如果该条件成立,则从A到F依次输出该人作案与否的判断结果。

为了让程序输出更加直观,想到用如下格式:

cout << “A” << info[A] <<endl;

cout << “B” << info[B] << endl;

我们已知变量A(或B,或C,或D,或E,或F)有0或1两种取值,

info[0] ——“不是罪犯”

info[1] ——“是罪犯”

这可以用定义字符类型的二维数组来实现。因为数组要在后面讲,这里提前使用,要先向学生说明一下,事先有所接触对学生来说也是有益的。

这样,就可以给出一个使用6重循环枚举6人中哪些人是罪犯的程序,之后让学生上机实践,弄懂并掌握这个程序的编写思路和技巧。

在此基础上,我们提出有没有可能不使用6重循环,而只用单层循环就可奏效的程序,这就属于进一步深入讨论的问题了。

思路是,A、B、C、D、E、F的64种排列,对应十进制数0,1,…,63。让循环控制变量为n

n=0,1,…,63,

知道n,一定能用之分解出A、B、C、D、E、F的值。借此,介绍二进制数位的概念,介绍C++提供的右移一位的运算符“>>”和“按位与”运算符“&”。

这时在循环体中要增加从n分离出A、B、C、D、E、F的语句

F=n&1;

E=(n&2)>>1;

D=(n&4)>>2;

C=(n&8)>>3;

B=(n&16)>>4;

A=(n&32)>>5;

书上也给出了这个程序的清单让学生上机学习。

这部分之后,留了4道有些难度的习题,目的是训练学生将一些话写成关系表达式和逻辑表达式的能力,并用枚举法将之解出,这也是检查这部分内容教学效果的一种方式。

总的来说,这部分内容看似在解决一道涉及破案的逻辑分析题,实际上教学要达到的目标是提高学生的计算思维能力,从最底层来加大抽象思维能力和逻辑思维方法的训练力度。会写关系表达式和逻辑表达式对编程是至关重要的,这一步上不去,后面会步步上不去。从这一课开始,我们强调理性思维和理性实践,强化上机动手动脑,编出来调不出来,不算真本事;编出的程序正确与否,要经过上机实践的检验,强调实践是检验真理的惟一标准。没有实践就没有提高能力的土壤。