【C语言】怎么用C语言来解逻辑推理题 | 运用离散数学+形式逻辑学的思想
最近在看波老师的形式逻辑学书籍,发现了一个很有趣的逻辑推理题,这个题的要求非常简单,就是判断一段话是对的还是错的,来看看这道逻辑题:
如果我有一千万,我就能买到房子。现在我没有一千万,我不能买到房子。
看完这道题目,我果断的断定,这是对的。结果答案是:错的!
知道真相的我,开始怀疑我的智商了。后来学了一小段时间的形式逻辑学后,我才理解了这道题为什么是错的。因为,如果我没有一千万,但是可能房子只需要一百万啊,所以我还是能买到房子的。又知道真相的我,被自己蠢哭了。。。
其实这道题的正确解法是用离散数学来解的,几乎现实中的含逻辑推理色彩的话语,都能转化成离散数学来演绎推理。简单来说,形式逻辑学,就是用离散数学来做逻辑推理(个人观点)。
------------------------------------------------------------------------------
先来简单回顾一下离散数学,对于一个陈述句,可以用真、假两个值来表示陈述句的正确性,真、假值用1、0来表示,同时用一个字母来表示这个陈述句,比如:
p : 小明吃饭了 1
┐p : 小明没有吃饭 0
q : 小红吃饭了 1
┐q : 小红没有吃饭 0
如果是有两个陈述句有关系,用相应符号表示,但是这个关系也是可能为真可能为假,这个很像程序代码的思维,再举例:
p∧q : 小明和小红都吃饭了
p∨q : 小明或者小红吃饭了
如果两个陈述句有因果关系,用→符号表示,比如:
p→q : 如果小明吃饭了,小红就吃饭了
离散数学还有更多语法,不再一一叙述,接下来是真值表的相关知识。
真值表,在数字逻辑电路中很常用的知识,简单点的有与非门、与或门的真值表,更难的有反馈电路等等,用真值表来分析电路的输入输出十分实用。离散数学的真值表跟数字逻辑的差不多,可能是同个祖宗。用离散数学的真值表思维来进行演绎推理,是一种很牛逼的方法,训练多了就分分钟成为下一个福尔摩斯。扯远了。。。回归正题,“小明吃饭了”这句话有真有假,那么真值表其实就是一张列举了所有真假关系的表,真值表也是离散数学的运算规则。
p:小明吃饭了 |
0 |
1 |
p
|
q | p∧q | p∨q |
0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 |
1 | 0 | 0 | 1 |
1 | 1 | 1 | 1 |
因果关系的真值表有点特殊,只有因是真的、果是假的情况时,整个推断就是假的,其他情况都是真的。为什么会这样子?因为如果前提是假的,那么结论不管结果是什么都没有意义,所以就把整个推断归为真的。还是不理解为什么会这样子的话,可以简单理解为吹牛吹大了,鬼知道真还是假,当是真的算了。
p | q | p→q |
0 | 0 | 1 |
0 | 1 | 1 |
1 | 0 | 0 |
1 | 1 | 1 |
======================================================================================
有了以上的离散数学基础知识,可以开始解那道逻辑题了:
如果我有一千万,我就能买到房子。现在我没有一千万,我不能买到房子。
(以下的解法有可能你会觉得发现了新大陆,反正我是觉得真的很神奇,再次体会到数学之美)
解:先把陈述句全部用字母和符号表示:
p : 我有一千万
q : 我能买到房子
┐p : 我没有一千万
┐q : 我不能买到房子
p→q : 如果我有一千万,我就能买到房子
┐p→┐q : 我没有一千万,我不能买到房子
有了以上的表示方式,就可以继续往下做,对于题目陈述句“如果我有一千万,我就能买到房子。现在我没有一千万,我不能买到房子。”这句话,有两种表示方式:
(1)(p→q)→(┐p→┐q)
(2)((p→q)∧┐p) → ┐q
为了接下来用C语言编写程序方便,我们来选用 第(2)种 方式列真值表
(这种方式的意思是把((p→q)∧┐p)当成前提条件,把┐q当成结论,通过合取p→q和┐p来推结论┐q是否正确):
p | ┐p | q | ┐q | p→q | ((p→q)∧┐p) | ((p→q)∧┐p)→┐q |
0 | 1 | 0 | 1 | 1 | 1 | 1 |
0 | 1 | 1 | 0 | 1 | 1 | 0 |
1 | 0 | 0 | 1 | 0 | 0 | 1 |
1 | 0 | 1 | 0 | 1 | 0 | 1 |
观察真值表,发现 ((p→q)∧┐p)→┐q 不是 重言式(全为真),因为其中有一个0。这就意味着,推理后可以判定这道题的逻辑是有问题的,是错的。在形式逻辑学中,有一个很重要的思 想,就是将一句话用字母和符号完整表示出来后,通过离散数学的运算规则列出真值表,如果表达式的真值中存在假即0时,就说明这句话的逻辑是错误的,推理是不成立的。
如果不知道((p→q)∧┐p)→┐q这个式子是怎么得出真值表的,只要把→符号的左右两边看成整体,再按照前面提到的运算规则即可得出真值表。
激动人心的时候到了,接下来我要用离散数学+形式逻辑学的思想用C语言编写程序来推理验证((p→q)∧┐p)→┐q的正确性。
(一)首先,我准备写一个函数,返回值为布尔型,命名为 decude,即推理的意思,先定义在main主函数之前,调用这个函数就相当于以上用离散数学解题的过程;
bool decude();
(二)现在开始编写decude,定义四个布尔变量,p为“我有一千万”,q为“我能买到房子”,condition为“我有一千万所以我能买房子”和“我有一千万所以我能买房子,现在我没有一千万”(之后会在代码动态变化),result为推理结果,默认为1即推理是正确的;
bool p;bool q;bool condition; bool result = 1;
(三)前面说过,离散数学中的因果关系的真值表十分特殊,只有因是真的、果是假的情况时,推理出的结果就是假的,其他情况都是真的。所以在代码中,可以通过以下代码来实现这个逻辑;
if( p==1 && q==0 ){condition = 0;}else{condition = 1;}
对应的真值表是:
p | q | p→q |
0 | 0 | 1 |
0 | 1 | 1 |
1 | 0 | 0 |
1 | 1 | 1 |
(四)当condition变量为“我有一千万所以我能买房子”时并且求出真值后,再合取“我能买到房子”q,又可得出新的condition,意思变为了“我有一千万所以我能买房子,现在我没有一千万”。简单来说,condition变量就是根据p→q的值再求出并被赋值成(p→q)∧┐p的真值;
condition = condition && !p;
(五)如果你没看懂以上四点,请先屡清楚逻辑。上面四点都只是针对某个确定的真值情况来求结果的,但是p和q的真值组合可以达到4种情况,所以,我要用for循环来把每一种真值情况都遍历一遍,才能推理出最终正确的结果;
//两层嵌套,嵌套内容语句最多执行四次,即可以把所有真值情况都遍历一遍for(int i=0; i<=1; i++){for(int j=0; j<=1; j++){p = i; //i为遍历p的真值,0为假,1为真q = i; //j为遍历q的真值,0为假,1为真/*其他内容。。。*/}}
(六)还记得还有一个变量result吗?默认为1,代表推理结果是正确的,但是在for循环中遍历的时候,如果result被修改为0,即已经计算出((p→q)∧┐p)→┐q的真值是0的时候,没有再循环的必要,所以要退出循环,最后将result值返回;
if(condition==1 && !q==0){result = 0;}if(result == 0){break;}
(七)以上六步,就是应用离散数学到C语言代码中的思想,接下来直接上完整代码:
#include <stdio.h>bool decude();int main(){bool result = decude(); //调用推理过程,获取返回值 if(result == 0){printf("经过推理后,得出结论不正确\n\n"); }else{printf("经过推理后,得出结论正确\n\n");}return 0;}//推理过程 bool decude(){bool p; //前提一:我有一千万bool q; //前提二:我能买到房子 bool condition; //前提三:如果我有一千万,我就能买到房子 bool result = 1; // 结论:我能买到房子 for(int i=0; i<=1; i++){ //遍历p前提一的真值 if(result == 0){ //如果得出结论是错误的,没有再循环下去的必要 break; //退出循环 }for(int j=0; j<=1; j++){ //遍历q前提二的真值 p = i; //将遍历到的i值赋给p当真值 q = j; //将遍历到的j值赋给q当真值 if( p==1 && q==0 ){ //如果p,则q的真值为假 condition = 0; //前提三 " 如果我有一千万,我就能买到房子 " 的真值为假 }else{condition = 1; //前提三 " 如果我有一千万,我就能买到房子 " 的真值为真 }//前提三变为前提四condition = condition && !p; //前提四: 如果我有一千万,我就能买到房子,现在我没有一千万 if(condition==1 && !q==0){ //如果 " 如果我有一千万,我就能买到房子,现在我没有一千万 ",则 " 我买不到房子 " 为假 result = 0; //得出推理结果的错误的 }if(result == 0){ //如果得出结论是错误的,没有再循环下去的必要 break; //退出循环 }}}return result; //循环结束后,返回推理结果 }
正文结束
本人形式逻辑学学得不深,所以上述难免会有误之处,而且写作水平不高,许多地方表述不够清楚,代码方面也没有用上好的算法,还请看完本文的大神多多指点。
【C语言】怎么用C语言来解逻辑推理题 | 运用离散数学+形式逻辑学的思想相关推荐
- R语言可视化绘图基础知识详解
R语言可视化绘图基础知识详解 图形参数:字体.坐标.颜色.标签等: 图像符号和线条: 文本属性: 图像尺寸及边界: 坐标轴.图例自定义等: 图像的组合: #install.packages(c(&qu ...
- php函数find的用法,c语言find函数的用法详解
c语言find函数的用法详解 C语言之find()函数 find函数用于查找数组中的某一个指定元素的位置. 比如:有一个数组[0, 0, 5, 4, 4]: 问:元素5的在什么位置,find函数 返回 ...
- java语言链栈_Java语言实现数据结构栈代码详解
近来复习数据结构,自己动手实现了栈.栈是一种限制插入和删除只能在一个位置上的表.最基本的操作是进栈和出栈,因此,又被叫作"先进后出"表. 首先了解下栈的概念: 栈是限定仅在表头进行 ...
- 大二c语言期末考试题库及详解答案,大学C语言期末考试练习题(带详解答案)...
<大学C语言期末考试练习题(带详解答案)>由会员分享,可在线阅读,更多相关<大学C语言期末考试练习题(带详解答案)(55页珍藏版)>请在金锄头文库上搜索. 1.一. 单项选择题 ...
- c语言线性表库函数大全,数据结构(C语言版)-线性表习题详解
<数据结构(C语言版)-线性表习题详解>由会员分享,可在线阅读,更多相关<数据结构(C语言版)-线性表习题详解(23页珍藏版)>请在人人文库网上搜索. 1.数 据 结 构 ,线 ...
- c语言 read 文件字节没超过数组大小时会怎样_剑指信奥 | C 语言之信奥试题详解(四)...
趣乐博思剑指信奥系列 ❝ 趣乐博思剑指信奥系列,专门针对全国青少年信息学奥林匹克联赛 NOIP 而开展的专业教育方案.开设的课程有 C 语言基础,C++ 语言基础,算法设计入门与进阶,经典试题分析与详 ...
- Go 语言 bytes.Buffer 源码详解之1
转载地址:Go 语言 bytes.Buffer 源码详解之1 - lifelmy的博客 前言 前面一篇文章 Go语言 strings.Reader 源码详解,我们对 strings 包中的 Reade ...
- C语言中指针与数组的区别,C语言 指针与数组的详解及区别
C语言 指针与数组的详解及对比 通俗理解数组指针和指针数组 数组指针: eg:int( *arr)[10]; 数组指针通俗理解就是这个数组作为指针,指向某一个变量. 指针数组: eg:int*arr[ ...
- gets和fgets函数及其区别,C语言gets和fgets函数详解
gets和fgets函数及其区别,C语言gets和fgets函数详解 每当讨论 gets 函数时,大家不由自主地就会想起 1988 年的"互联网蠕虫",它在 UNIX 操作系统的 ...
- 基于C语言的JPEG编码代码详解
一.基于C语言的JPEG编码代码详解 #include <stdio.h> #include <stdlib.h> #include <string.h>#prag ...
最新文章
- 网页设计师的必备选择20 +必需的Windows应用程序
- Linux 创建用户分配文件夹权限
- arcgis 10.0中的server报错说工作站服务没有打开
- 前端综合能力系列之git与gitflow
- TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常!...
- Java 多态,接口
- 数据库服务器日常维护完全情况表格,数据库日常维护.doc
- matlab:在FUNCTION处出现解析错误:使用的MATLAB语法可能无效。
- 巧妙设置excel透明字体
- java.sql.SQLException: Access denied for user ‘root‘@‘127.0.0.1‘ (using password: YES)
- 巅峰战舰 服务器维护,《巅峰战舰》停止充值关闭服务器公告
- 阿里P7亲自教你!2021Java不死我不倒
- 来自CodeSmith的震撼
- el-input 正则,非负数且只有一个小数点
- 不同性质的公司在英文中不同说法
- Nginx的http_access_module模块
- 【应用篇】MyBatis学习笔记
- 浅谈Uber与滴滴快的提供差异化服务带来的商业模式思考
- 江苏图采之证件照上传
- 看Google收购Nest
热门文章
- BusinessSkinForm VCL
- 终于明白了AOP中的方面是什么意思
- android/ios播放器ijkplayer Ubuntu编译(支持HTTPS、ffmpeg高版本)
- 上海地铁二号线和一号线的差距
- 【TensorFlow】tf.expand_dims()函数
- PAT乙级 1068 万绿丛中一点红 (20 分) Java 实现
- wifi动不动就断开_笔记本Wifi上网经常间歇性断网的修复
- java即时通讯 开源_java开源即时通讯软件服务端openfire源码构建
- 面试常问--你是否曾经得到过低于自己预期的成绩?如果得到过,你是怎样处理这件事情的?
- 【板子】 0-1背包问题 一维数组