使用双栈实现输出逻辑表达式的真值表
来源:互联网 发布:ppp和hdlc对数据的 编辑:程序博客网 时间:2024/06/05 15:00
目的:读入一个逻辑表达式,包含多个变量及各种逻辑运算,输出该逻辑表达式的真值表;
思路:
1.与计算多项式的思路一致,利用双栈存储从左到右遍历;
栈具有LIFO的特点,利用栈可以储存离当前操作符最近的符号与数据,从左到右遍历,直到最终得出表达式的值;
2.两个栈一个存储符号,一个存储数据,设置栈内栈外符号位的优先级;
相同符号栈内优先级大于栈外优先级;
左括号栈内优先级最高,栈外优先级紧大于‘#’;
右括号与左括号相反;
将‘#’优先级设为最低,放入栈底,方便比较并判断终止条件;
3.每次读入一位,若为数据入数据栈;若为操作符,进行优先级比较
当栈内运算符优先级大于栈外运算符优先级,执行运算;
当栈内运算符优先级等于栈外运算符优先级,必为左右括号,弹出左括号;
当栈内运算符优先级小于栈外运算符优先级,将该符号入栈;
代码实现:
#include <iostream>#include <iomanip>#include <stdio.h>#include <stdlib.h>#include <cstring>#include <algorithm>#include <stack>#include <map>#include <cmath>using namespace std;int num[10];//按位存储生成的二进制码int letter_num;//全局变量存储表达式中变量数目map<char,int> m;//用map将字符与数字绑定,方便对应char letter[10];//储存所有字符变量char relation[256];//储存关系表达式int show[100];//记录变量是否出现int in[]={3,3,3,3,4,1,5,0};//栈内优先级int out[]={2,2,2,2,4,5,1,0};//栈外优先级char symbol[]={'^','V','>','<','~','(',')','#'};//储存操作符int get(char x);//返回操作符对应下标void get_num(int x);//更新按位二进制表示int get_letter_num(char *);//统计并储存变量char com(char x1,char x2);//比较优先级bool if_variable(char x);//判断当前字符是否为变量void print_truth_table(char *);//打印真值表int figure(int x1,int rel,int x2);//计算基本表达式值int main(){ cin>>relation; print_truth_table(relation); return 0;}void print_truth_table(char* top){ int sum; char* y; int x,x1,x2; char rel; stack<int> data;//存储数据 stack<int> ope;//存储操作符/*初始化*/ memset(show,0,sizeof(show)); memset(letter,0,sizeof(letter)); memset(num,0,sizeof(num)); ope.push(get('#')); y=top; x=get_letter_num(top); x=(int)pow(2,x);//对应于2^x数的真值表/*打印表头*/ for(int i=0;i<=letter_num;i++) { if(i==letter_num) { printf("%-10s\n",relation); for(int j=0;j<=letter_num;j++) cout<<"----------"; cout<<endl; continue; } printf("%-10c",letter[i]); } while(x--) { top=y;//保存头指针,每次遍历完需重置 get_num(x);//更新二进制表示 int index=ope.top(); while(*top||index!=7) { sum=0; if(*top=='-') top++; if(*top=='~')//取非将4压入操作栈 { ope.push(4); top++; } if(*top=='<')//若为等价符另右移两位 { ope.push(get(*top)); top+=3; } if(if_variable(*top))//压入变量值 { sum=m[*top]; data.push(sum); top++; } else//符号操作 { switch(com(symbol[ope.top()], *top)) { case 1://'>' if(ope.top()==4)//取反单独计算 { x1=data.top(); data.pop(); x1=(x1+1)%2; data.push(x1); ope.pop(); break; } x1=data.top(); data.pop(); x2=data.top(); data.pop(); rel=ope.top(); ope.pop(); data.push(figure(x1,rel,x2)); break; case 2://'<' ope.push(get(*top)); if(*top) top++; break; case 3://'=' ope.pop(); if(*top) top++; break; } } index=ope.top(); }/*打印结果*/ for(int i=0;i<=letter_num;i++) { if(i==letter_num) { printf("%d\n",data.top()); data.pop(); continue; } printf("%-10d",num[i]); } } return ;}void get_num(int x){ for(int i=letter_num-1;i>=0;i--) { num[i]=x%2; m.erase(letter[i]); m.insert(make_pair(letter[i],num[i])); x/=2; } return ;}int get(char x){ switch(x) { case '^': return 0; case 'V': return 1; case '>': return 2; case '<': return 3; case '~': return 4; case '(': return 5; case ')': return 6; case '#': return 7; default: return 7; }}int get_letter_num(char *x){ letter_num=0; while(*x) { switch(*x) { case '^': case 'V': case '>': case '<': case '(': case ')': case '#': case '-': case '~': x++; break; default: if(!show[(int)*x]) { letter[letter_num]=*x; letter_num++; show[(int)*x]=1; } x++; break; } } return letter_num;}char com(char x1,char x2){ int i1=get(x1); int i2=get(x2); if(in[i1] > out[i2]) return 1; else if(in[i1] < out[i2]) return 2; else return 3;}bool if_variable(char x){ switch(x) { case '^': case 'V': case '>': case '<': case '(': case ')': case '#': case '\0': return false; default: return true; }}int figure(int x1,int rel,int x2){ switch(rel) { case 0: return x1&&x2;//与 case 1: return x1||x2;//或 case 2: return x1||!x2;//蕴含 case 3: return (!x1&&!x2)||(x1&&x2);//等价 } return 0;}
0 0
- 使用双栈实现输出逻辑表达式的真值表
- 电路与Multisim 逻辑变换器的使用,输入真值表,获得逻辑表达式
- 逻辑表达式化为真值表
- [Python] 逻辑表达式的真值表以及卡诺图生成
- 利用栈求逻辑运算表达式的真值
- js中的逻辑表达式是按照真值、假值区分
- 5.6 数码管的真值表
- 关于离散数学的真值表的求解
- 求两个变量的真值表C++
- 真值表的遍历(C语言版)
- 【离散数学】实验一 利用真值表法求取主析取范式以及主合取范式的实现
- 利用真值表法求取主析取范式以及主合取范式的实现
- 南邮离散数学实验 利用真值表法求取主析取范式以及主合取范式的实现
- 如何使用logisim的真值表自动生成电路?【木森小教程】
- 表达式计算,输出后缀表达式,栈实现
- 利用真值表法求主合取范式及主析取范式的实现
- 递归实现布尔(boolean)真值表全排列--C语言版
- C语言 实现离散数学合式公式真值表
- 关于exlipse启动时jdk版本问题
- bash条件测试之空字符串的困惑
- jsp <c:set>标签的使用
- PocketCloud Computer Era
- iOS 之GCD和Block
- 使用双栈实现输出逻辑表达式的真值表
- 用宏定义最大值
- loadrunner的ie代理问题
- INSTALL_PARSE_FAILED_NO_CERTIFICATES异常
- IOS证书/私钥/代码签名/描述文件
- Scan IP relocate/failover后其他网段无法ping通
- Java中IO流(3)——字符流缓冲区(传智播客毕老师视频讲解)
- StoryBoard初探(三):自定义Segue以及页面间传值
- iOS 之Cocoa框架