描述

这学期我们正在学习离散数学,离散数学可以称为计算机数学,是以后很多计算机专业课的基础课。

现在我们尝试用计算机编程去解决离散数学中的问题,既可复习离散数学,又可进行编程实践,可谓两全其美。

任务

编程序判断一个命题公式是否为永真公式 ( 又称为重言式 ) 。

永真公式定义为:给定一个命题公式,若无论对分量作怎样的指派,其对应的真值永为真。

在此,我们限定所出现的命题联结词只有 4 种,即否定 ( 用 not 来表示 ) 、合取 ( 用 and 来表示 ) 、析取 ( 用 or 来表示 ) 、条件联结词 (又称蕴含联结词, 用 then 来表示 ) ,每个原子命题用一个大写英文字母来表示。

输入

一次输入可能包含多组数据。每组数据占用一行。当输入 end 的时候结束。

注意每个联结词前后都有空格, not 位于一行开始的时候前面可以没有空格。原子命题与小括号之间可以没有空格。

联结词的优先级在输入中通过小括号已经全部体现出来,编程时只需判断小括号就可以了。

每组测试用例输入的字符串长度不超过 1000.

输出

针对每一组输入,如果该命题公式为永真公式,输出 1 ;否则输出 0 。

样例输入
( not P) then (P then Q)
((P or S) and R) or ( not ((P or S) and R))
(P and Q) then M
end
样例输出
1
1
0
模拟题,分情况讨论
#include "stdio.h"
#include "string.h"
#include "math.h"
#define AND 1
#define OR 2
#define THEN 3
#define NOT 4
#define TRUE 1
#define FALSE 0
#define MAX_SIZE 1100void transform(int start_pos,int end_pos,char formular[])
{int i,j,variable[2];    /* variable记录公式中出现的命题变元的值 */int flag;               /* flag 标记该公式中是否含有逻辑运算词 */int op;                 /* op 记录逻辑运算词 */int res;     /* 括号内的值 */j=0;flag=0;for (i=start_pos;i<=end_pos;i++){if ( formular[i]=='0' || formular[i]=='1' ){variable[j++]=formular[i]-48;}if ( formular[i]>='a' && formular[i]<='z' )  /* 遇到逻辑运算词 */{flag=1;/* 记录逻辑运算词 */switch (formular[i]){case 'a':op=AND;i+=2;break;case 'o':op=OR;i+=1;break;case 't':op=THEN;i+=3;break;case 'n':op=NOT;i+=2;break;}}}if ( flag )   /* 包含逻辑运算符 */{switch (op){case AND:res=variable[0] & variable[1];break;case OR:res=variable[0] | variable[1];break;case THEN:res= ( ( variable[0]==1 && variable[1]==0 )? 0 : 1 );break;case NOT:res=( ( variable[0]==1 )? 0 : 1 );break;}}else{res=variable[0];}formular[start_pos]=res+48;for (i=start_pos+1;i<=end_pos;i++){formular[i]=' ';}return ;
}int Judge(char formular[])   /* 判断该公式是否为永真公式,是则返回TRUE */
{int search(char formular[],char F[]);int get_res(char formular[]);char variable[30];      /* 存储各个变元的真值 */char F_var[30];         /* 对应的关系 */char temp[MAX_SIZE];    /* 用真值来替代各个命题变元的字符串 */int n,j;                  /* n的值为该命题公式的命题变元的数量 */int flag;long i,max,temp_i;n=search(formular,F_var);max=pow(2,n)-1;/* 枚举所有情况以确定是否为永真公式 */for (i=0;i<=max;i++){temp_i=i;/* 依次给各个命题变元赋真值 */for (j=n;j>=1;j--){variable[F_var[j]-64]=temp_i%2+48;temp_i=temp_i/2;}/* 替换命题变元 */for (j=0;formular[j]!='\0';j++){if ( formular[j]>='A' && formular[j]<='Z' )  /* 遇到命题变元,用真值替换 */{temp[j]=variable[formular[j]-64];}else{temp[j]=formular[j];}}temp[j]='\0';/* 计算在该真值下此命题公式的值 */flag=get_res(temp);if ( flag==FALSE )return FALSE ;}return TRUE ;
}int search(char formular[],char F[])  /* 该函数求一个公式的命题变元的数目,并讲命题变元依次存入F[]的映射关系中 */
{int i,j,count,flag;count=0;for (i=0;formular[i]!='\0';i++){if ( formular[i]>='A' && formular[i]<='Z' ){flag=0;for (j=1;j<=count;j++){if ( F[j]==formular[i] ){flag=1;   /* 说明该命题变元出现过,不记录 */}}if ( !flag ){F[++count]=formular[i];}}}return count ;
}int get_res(char formular[])    /* 计算一个已经给各个命题变元指派真值的命题公式的真值 */
{void transform(int start_pos,int end_pos,char formular[]);int i,j,flag;   /* flag 记录该命题公式中是否还存在括号 */int left,right;  /* 分别记录左括号和右括号的位置 */flag=FALSE;left=0;right=0;for (i=0;formular[i]!='\0';i++){if ( formular[i]=='(' ){left=i;}if ( formular[i]==')' ){flag=TRUE;right=i;break;}}while ( flag ){transform(left+1,right-1,formular);/* 判断,消去括号 */formular[left]=' ';formular[right]=' ';/* 继续判断是否存在括号 */flag=FALSE;for (i=0;formular[i]!='\0';i++){if ( formular[i]=='(' ){left=i;}if ( formular[i]==')' ){flag=TRUE;right=i;break;}}}transform(0,strlen(formular)-1,formular);for (i=0;formular[i]!='\0';i++){if ( formular[i]=='1' ){flag=TRUE;break;}else if ( formular[i]=='0' ){flag=FALSE;break;}}return flag;
}int input(char formular[])    /* 处理输入的函数 */
{gets(formular);if ( formular[0]=='e' )return TRUE;return FALSE ;
}int main(void)
{char formular[MAX_SIZE];int end;end=input(formular);while ( end==FALSE ){printf("%d\n",Judge(formular));;end=input(formular);}return 0;
}



1836 永真公式的验证相关推荐

  1. 数理逻辑蕴含_数理逻辑 脉络梳理

    逻辑学 是一门研究思维形式及思维规律的科学. 逻辑规律就是客观事物在人的主观意识中的反应. 逻辑学分类 辩证逻辑 形式逻辑 思维的形式结构 概念 -- 是思维的基本单位 判断 -- 通过概念对事物是否 ...

  2. 离散数学知识点总结-命题逻辑

    目录 命题 逻辑连接词 命题符号化 命题公式及其赋值 命题公式的等价 重言式与矛盾式 重言蕴含式 范式 主析取范式 主合取范式 命题逻辑推理 直接推理 间接推理 命题 命题是表达判断的陈述句. 判断一 ...

  3. 【离散数学】第二章 笔记(完)

    写在前面 是复习的笔记.截图是老师的课件. 2.1 谓词 谓词的概念与表示: 谓词:用来刻划一个个体的性质或多个个体之间关系的词,常用大写字母P, Q, R-来表示. 客体:可以独立存在的事物称为客体 ...

  4. [离散数学]命题逻辑P_5:命题公式分类和等价

    [离散数学]命题逻辑P_5:命题公式分类和等价 前言 1. 真值表告诉我们什么? 例子 2. 命题公式分类 定义 例子 3. 公式的逻辑等价 定义 定理 证明 总结 前言 第五讲:命题公式分类和等价 ...

  5. 【离散数学】1. 数理逻辑

    1.数理逻辑 2. 集合论 3. 代数系统 4. 图论 离散数学:研究离散量结构及相互关系的学科 数理逻辑 集合论 代数系统 图论 逻辑:研究推理的科学 数学方法:引进一套符号系统的方法 数理逻辑是用 ...

  6. 离散数学数理逻辑部分【2】

    文章目录 命题逻辑 等值演算公式的使用[重点] 析取范式和合取范式[重点] 范式存在定义[了解] 求公式A的范式的步骤:[重点] 极大项和极小项[重点] 主合取范式和主析取范式[重点] 等式演算求主析 ...

  7. 计算机考博方向数学,2016华中科技大学考博:计算机数学考试大纲

    2016华中科技大学考博:计算机数学考试大纲 研究生院发布的考博大纲是考生们参考复习的权威资料,考试大纲包括了考试内容范围.考试题型和分值分配,有时其中还会包括参考书目.请考生们认真阅读. <计 ...

  8. 离散数学知识点【复试】

    1.极大项是析取,极小项是合取. 2.每个极小项只有一组成真赋值,因此可用于给极小项编码.编码规律为:命题变元与1对应,命题变元的否定与0对应. 3.每个极大项只有一组成假赋值,因此可用于给极大项编码 ...

  9. 程序验证(四):一阶理论

    程序验证(四):一阶理论 定义 一个一阶理论(theory)TTT被以下两点定义: 它的符号集Σ\SigmaΣ, 一个非逻辑符号的集合 它的公理A\mathcal{A}A, 一个在Σ\SigmaΣ上的 ...

最新文章

  1. 大巧不工-WEB前端设计修炼之道pdf
  2. C语言 输入一个正整数n,再输入n个字符,如果是小写字符就将其转换为大写字符,如果是大写字符就 转换为小写字符
  3. 如何安装SAP JCo3
  4. Django 权限管理
  5. 快速启动栏的现实桌面快捷方式
  6. NumPy之:理解广播
  7. VS11在Win8上的Metro应用
  8. 日语python怎么说_python+Mecab,一次性学会日语分词
  9. 第一站---大连---看海之旅
  10. MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用
  11. opengl es的射线拾取
  12. PHP中获取html页面传值
  13. 2021年1月PMP考试改版
  14. python爬虫文献_Python文献爬虫①
  15. 华为手机海拔测试软件,华为手机海拔高度测量仪
  16. LOJ2482 CEOI2017 Mousetrap 二分答案、树形DP
  17. 计算机全盘搜索功能不见了,win7搜索功能不见了两种恢复方法(图文)
  18. [转]移动App测试中的最佳做法
  19. ArcGIS——使用符号级别区分重叠的面图层
  20. 什么是UV贴图和展开?没有他们3D建模会变成什么样?来看看!

热门文章

  1. Java中的栈内存和堆内存
  2. 一文搞懂 checkpoint 全过程
  3. 顶底突破同花顺副图指标 波浪类指标
  4. BLAS库不同厂商实现合集(2022)
  5. 泊松分布与泊松回归模型
  6. Parse 使用教程之四
  7. 区块链实验三 : 区块链编程2
  8. 黑马程序员MySQL数据库之基础篇笔记(SQL语法)(每日更新)
  9. loadrunner快捷键
  10. Linux安装mysql8.0.26版本