计算主析取范式

【问题描述】
请根据给定的命题公式,计算其真值为T的小项,列出主析取范式,并输出结果。
【输入形式】
输入一个字符串(字符串长度<=50)形式的命题公式,以回车表示输入结束。其中的命题公式为仅包含原子命题、联结词和括号的合式公式。联结词仅包含下述5中联结词:
1、否定,表示为“!”
2、合取,表示为“*”
3、析取,表示为“|”
4、条件,表示为“-”
5、双条件,表示为“=”
例如:
(P-Q)-R
注意:输入符号均采用英文输入。
【输出形式】
输出一个以单个空格分隔的字符串,字符串中各项分别对应主析取范式中小项的序号。
如(P-Q)- R对应的小项为
则输出1 3 4 5 7
注意:其中的原子命题按字母表排序。
【样例输入】
(P-Q) - R
【样例输出】
1 3 4 5 7

解题思路
0.真值表法基础
定义:
在真值表中,一个公式的真值为T的指派所对应的小项的析取,即为公式的主析取范式。

1.代码实现
给各个原子命题设定初值(T/F),然后计算命题公式的真值,如果为真,就输出原子命题对应的数字。
先对字母赋初值,赋值的方式是把数字转化为二进制序列,然后按照字母顺序一个一个赋值。具体实现方式看下面代码。

代码

#include<bits/stdc++.h>
#include<set>
#define N 55
using namespace std;
bool Flag[N];
set<char> Set;  //用来存储用了哪些字符
map<char,char> Map;
//          (!P*Q)|(P*!Q)
char Calculate(char a,char op,char b){if( op == '*' ){if( a == b && b == '1' ) return '1';else return '0';}else if( op == '|' ){if( a == b && b == '0' ) return '0';else return '1';}else if( op == '-' ){if( a == '1' && b == '0' ) return '0';else return '1';}else if( op == '='){if( a == b ) return '1';else return '0';}
}//检测不带括号的字符串
char Check(string tem){    //tem是01字符 int Negation,AndOr,Condition; int temlen = tem.size(); // !运算for(int i = 0;i < temlen; i++){if(tem[i]!='!') continue; int ri = i;tem[i] = ' '; while(tem[i]!='0' && tem[i]!='1'){i++;}if(tem[i]=='0') tem[i] = '1';else tem[i] = '0'; }  temlen = tem.size();// *和|运算for(int i = 1;i < temlen;i++){if(tem[i]!='*' && tem[i]!='|') continue; int li = i,ri = i;while(tem[li]!='0' && tem[li]!='1') li--;while(tem[ri]!='0' && tem[ri]!='1') ri++;tem[i] = Calculate(tem[li],tem[i],tem[ri]);tem[li] = ' ',tem[ri] = ' ';} //-和=运算for(int i = 1;i < temlen;i++){if(tem[i]!='-' && tem[i]!='=') continue;int li = i,ri = i;while(tem[li]!='0' && tem[li]!='1') li--;while(tem[ri]!='0' && tem[ri]!='1') ri++;tem[i] = Calculate(tem[li],tem[i],tem[ri]);tem[li] = ' ',tem[ri] = ' ';} //返回结果 for(int i = 0;i<temlen;i++) if(tem[i]=='1') return '1';return '0';
}//检查带括号的逻辑表达式
bool CheckWithParentheses(string tem){stack<char> Sta;int temlen = tem.size();for(int i = 0;i<temlen;i++){//处理每个字符if(tem[i] == ')'){//字符串匹配string str = "";int Size = Sta.size();  while(Size--){char C = Sta.top();Sta.pop();if(C == '(') {Sta.push(Check(str));break;}str = C + str; } } else{Sta.push(tem[i]); } }//所有的括号都去掉了,检查最后的表达式string str = "";while(Sta.size()) str = Sta.top()+str,Sta.pop();if(Check(str)=='0') return 0;return 1;
}//更新Flag数组
void Initial(int K){int len; memset(Flag,0,sizeof(Flag));for(int i = 0 ; i <= 55; i++){Flag[i] = K%2;len = i;K/=2;if( K==0 ) break;} return ;
}//把字母换成01值
string Transform(string s){//遍历字符串,将字母加入set中int lens = s.size(); //给对应的字母赋值0或1int pos = 0;auto it = Set.end();while(1){it--; Map[*it] = int(Flag[pos++])+'0';  if(it == Set.begin()) break; } //改变字符串for(int i = 0;i < lens;i++){if(isalpha(s[i])){s[i] = Map[ s[i] ] ;}} return s;
}  //求a的n次方
int qpow(int a, int n) {if (n == 0)return 1;else if (n % 2 == 1)return qpow(a, n - 1) * a;else{int temp = qpow(a, n / 2);return temp * temp;}
}int main(){ string s,Storage;cin>>s; Storage = s;//字母加进集合中 int lens = s.size();for(int i = 0; i < lens ; i++){if(isalpha(s[i])) Set.insert(s[i]);} //初始化测试int Max = qpow(2,Set.size()); for(int i = 0;i < Max ;i++){ s = Storage;Initial(i);  //把字母变成01符号 s = Transform(s);   if( CheckWithParentheses(s) ) cout<<i<<' ';   }cout<<endl; return 0;
}/*
1、否定,表示为"!"      直接取反
2、合取,表示为"*"      同真为真
3、析取,表示为"|"      同假为假
4、条件,表示为"-"      前真后假为假
5、双条件,表示为"="    相同为真
*/ 

离散数学:计算主析取范式(基于真值表)相关推荐

  1. 【离散数学】计算主析取范式(基于真值表)

    [问题描述] 请根据给定的命题公式,计算其真值为T的小项,列出主析取范式,并输出结果. [输入形式] 输入一个字符串(字符串长度<=50)形式的命题公式,以回车表示输入结束.其中的命题公式为仅包 ...

  2. 离散数学范式c语言实验报告,离散数学实验报告-利用真值表法求主析取范式及主合取范式的实现...

    1.实 验 报 告( / 学年 第 一 学期)课程名称离散数学实验名称利用真值表法求主析取范式及主合取范式的实现实验时间年月日指导单位指导教师学生姓名班级学号学院(系)专 业 实 验 报 告实验名称利 ...

  3. 【离散数学】Java语言实现利用真值表法求主析取范式和主合取范式

    C++版本的看这个链接: [离散数学]C++语言实现利用真值表法求主析取范式和主合取范式_zhtstar的博客-CSDN博客https://blog.csdn.net/weixin_56319483/ ...

  4. 【离散数学】C++语言实现利用真值表法求主析取范式和主合取范式

    Java版本的如下链接所示: Java语言实现利用真值表法求主析取范式和主合取范式_zhtstar的博客-CSDN博客https://blog.csdn.net/weixin_56319483/art ...

  5. 离散实验 真值表求主析取范式、主合取范式的计算机语言实现

    离散数学 实验一 标题:真值表求主析取范式.主合取范式的计算机语言实现 其他课程的一些其他实验源码也可在本人github主页找到哦 链接如下:https://github.com/Schiz0mani ...

  6. 离散数学实践一编程判断主析取范式和主合取范式【java实现】

    文章目录 实验要求 二 编程思路分析 困难所在 二 完整代码 实验要求 实验类型:设计性 实验目的 通过算法设计并编程实现,使学生掌握利用计算机语言判别合式公式主范式的基本方法. 实验内容 给定合式公 ...

  7. 南京邮电大学离散数学实验一【计算主范式(Java)】

    ** 计算主范式 ** 实验目的和要求 目的:对任意给出的一个命题公式,使学生会利用编程语言表示出来,并且能够计算出该公式的主析取范式和主合取范式. 要求:使用编程语言,如C/C++.Java等可视化 ...

  8. 【c++】[自动生成真值表/主析取范式/主合取范式的计算器]

    关于自动生成真值表/主析取范式/主合取范式的计算器 我用c++写了一个,需要的自取,如果好用请点赞 链接:https://pan.baidu.com/s/1Ji1zPDtjAc6-TDxovEzMVw ...

  9. 【数理逻辑】范式 ( 合取范式 | 析取范式 | 大项 | 小项 | 极大项 | 极小项 | 主合取范式 | 主析取范式 | 等值演算方法求主析/合取范式 | 真值表法求主析/合取范式 )

    文章目录 一. 相关概念 1. 简单 析取 合取 式 ( 1 ) 简单合取式 ( 2 ) 简单析取式 2. 极小项 ( 1 ) 极小项 简介 ( 2 ) 极小项 说明 ( 3 ) 两个命题变项 的 极 ...

最新文章

  1. Linux环境编程--fflush(stdout)有什么作用
  2. 53.垃圾回收算法的实现原理、启动Java垃圾回收、Java垃圾回收过程、垃圾回收中实例的终结、对象什么时候符合垃圾回收的条件、GC Scope 示例程序、GC OutOfMemoryError的示例
  3. java怎么获取字符串位置,Java:在字符串中获取匹配位置的方法?
  4. [Swift]LeetCode1035.不相交的线 | Uncrossed Lines
  5. [hdu5372 Segment Game]树状数组
  6. 微信开发经常会用到的一些方法
  7. 数据绑定控件Reperter
  8. 操作系统导论 书中代码下载_经典教材统计学习导论终于有Python版了(附下载)...
  9. SOEM主站开发笔记-- 点亮第一个LED----SOEM 的simpletest.c代码的解析以及改动
  10. iOS TestFlight 使用详解
  11. 湖北省疫情数据可视化分析
  12. 42表盘直径是从哪测量_手表尺寸怎么选择 手表尺寸怎么测量
  13. HMAC和密钥导出(HMAC and Key Derivation)
  14. 科技云报道:安全脱管不如托管
  15. win10运行安卓模拟器蓝屏崩溃
  16. QQ空间中的日志在不同用户的主页显示不同QQ号方法
  17. 日均5亿查询量的京东到家订单中心,为什么舍MySQL用ES?
  18. Spring下载教程(保姆级)
  19. 小程序----分账功能开发
  20. java微信公众号开发四步完成

热门文章

  1. HTML5+CSS3 鼠标悬停3D立体图片效果
  2. 计算机显卡驱动全部卸载,Win7如何彻底卸载NVIDIA显卡驱动程序有哪些方法
  3. 计算机丢失d3dx935.dll,d3dx9_39.dll
  4. 用虚拟打印机实现文档格式的转换
  5. ubuntu20.04官方安装I219-V驱动
  6. html5制作颜色的诗句,写颜色的诗句
  7. 由量变到质变 写出高质量代码
  8. 图像处理:模糊图像判断
  9. html加载m3u8
  10. NTT帮助印第安纳波利斯赛车场增强INDYCAR车迷体验和安全性