利用栈求逻辑运算表达式的真值
2015-03-29 21:27
295 查看
今天浙江理工校赛的D题。
比赛结束后在网上看了文章才做出来的。
Submit: 248 Solved: 36
给你一个与或非的表达式,求出这个表达式的值,表达式总共有八种字符。
三种逻辑运算符按照优先级排列如下。
‘!’:表示取反。
‘&’:逻辑与。
‘|’:逻辑或。
两个字符‘T’,‘F‘分别表示true和 false。
另外还有左右括号,空格三种字符。跟一般的表达式一样,括号可以改变优先级。
用2个栈,一个存储运算符,一个存储运算的数字。
对于连个相继出现的操作符θ1和θ2 有三种关系:大于、等于和小于。由此可以列出“+-*/”之间的优先级。如下表:
! &
| (
) #
! >
> >
< >
>
& <
>
>
<
>
>
| < <
>
<
>
>
( <
<
<
<
=
>
) >
>
>
<
>
>
# <
<
<
<
>
=
为了算法简洁,在表达式的左边和右边虚设一个“#”,这一对“#”表示一个表达式求值完成。
“(” = “)” 当一对括号相遇时表示括号内已运算完成。
“)”和“(”、“#”和“(”、“(”和“#”无法相继出现如果出现则表达式出现语法错误。
为实现优先算法,可以使用两个工作栈,一个是Q,用于寄存运算符,一个是P,用于寄存运算数和运算结果。
依次读入表达式中的每个字符,若是操作数则进Q栈,若是运算符则和Q栈的栈顶运算符比较优先权作相应操作,直至整个表达式求值完毕(Q栈顶元素和当前读入的字符均为“#”)
比赛结束后在网上看了文章才做出来的。
Problem D: 逻辑运算
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 248 Solved: 36
Description
还记得大学里学过的模电么,今天就让我们将与或非变成一道题吧。给你一个与或非的表达式,求出这个表达式的值,表达式总共有八种字符。
三种逻辑运算符按照优先级排列如下。
‘!’:表示取反。
‘&’:逻辑与。
‘|’:逻辑或。
两个字符‘T’,‘F‘分别表示true和 false。
另外还有左右括号,空格三种字符。跟一般的表达式一样,括号可以改变优先级。
Input
每组数据输入一行字符串,字符串长度小于等于100.Output
输出一个数0或1,表示逻辑表达式的答案。Sample Input
T
Sample Output
1
用2个栈,一个存储运算符,一个存储运算的数字。
对于连个相继出现的操作符θ1和θ2 有三种关系:大于、等于和小于。由此可以列出“+-*/”之间的优先级。如下表:
! &
| (
) #
! >
> >
< >
>
& <
>
>
<
>
>
| < <
>
<
>
>
( <
<
<
<
=
>
) >
>
>
<
>
>
# <
<
<
<
>
=
为了算法简洁,在表达式的左边和右边虚设一个“#”,这一对“#”表示一个表达式求值完成。
“(” = “)” 当一对括号相遇时表示括号内已运算完成。
“)”和“(”、“#”和“(”、“(”和“#”无法相继出现如果出现则表达式出现语法错误。
为实现优先算法,可以使用两个工作栈,一个是Q,用于寄存运算符,一个是P,用于寄存运算数和运算结果。
算法基本思路。
首先置操作数栈为空栈,表达式起始符为“#”为栈底元素。依次读入表达式中的每个字符,若是操作数则进Q栈,若是运算符则和Q栈的栈顶运算符比较优先权作相应操作,直至整个表达式求值完毕(Q栈顶元素和当前读入的字符均为“#”)
代码实现:
<pre name="code" class="cpp"><span style="font-size:14px;">#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <string> #include <algorithm> #include <queue> #include <stack> using namespace std; const double PI = acos(-1.0); const double e = 2.718281828459; const double eps = 1e-8; const int MAXN = 110; char s[MAXN]; char opset[6] = {'!','&','|','(',')','#'}; char prio[6][6] = { '>', '>', '>', '<', '>', '>', '<', '>', '>', '<', '>', '>', '<', '<', '>', '<', '>', '>', '<', '<', '<', '<', '=', '>', '>', '>', '>', '<', '>', '>', '<', '<', '<', '<', '>', '=', }; //找到对应运算符在 opset 数组的下标 int findindex(char op) { for(int i = 0; i < 6; i++) { if(opset[i] == op) return i; } } //比较Q栈顶元素与当前s[i]中运算符的优先级 char compare(char a, char b) { int x = findindex(a); int y = findindex(b); return prio[x][y]; } //计算 x y 在op运算符下的结果 int calc(int x, int y, char op) { if(op == '|') return x|y; if(op == '&') return x&y; return 0; } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); while(scanf("%s", s) != EOF) { int lens = strlen(s); s[lens] = '#'; // s 数组尾部存为'#' s[lens+1] = '\0'; int t, x, y; char op; int i = 0; stack<int>P; // 用于存储运算数,整数元素 stack<char>Q; //用于存储运算符号,字符元素 Q.push('#'); //把栈底存为 '#' while(s[i]!='#' || Q.top()!='#') { //当s数组读到末尾,且Q已经读到栈底,说明全部运算结束 if(s[i]=='T' || s[i]=='F') { //读取到 T 或 F, 转化为0 或 1入栈 if(s[i] == 'T') t = 1; else t = 0; P.push(t); i++; } else if(s[i] != ' ') { //由于输入的字符串包含空格,所以要空格要略过 switch(compare(Q.top(), s[i])) { case '<': // 栈顶元素优先级低,则当前元素入栈 Q.push(s[i]); i++; break; case '=': // 左右括号匹配,脱括号并接收下一字符 Q.pop(); i++; break; case '>': // 退栈并将运算结果入栈 if(Q.top() == '!') { // 栈顶元素为 !,单目操作符 x = P.top(); P.pop(); P.push(!x); Q.pop(); } else { // 栈顶元素不是 ! x = P.top(); P.pop(); y = P.top(); P.pop(); op = Q.top(); Q.pop(); //计算结果并入栈 P.push(calc(x, y, op)); } break; } } } int ans = P.top(); cout<<ans<<endl; } return 0; } </span>
相关文章推荐
- [Java算法分析与设计]利用栈操作中缀表达式和后缀表达式的转换和运算
- 基于逻辑表达式的集合运算
- 视频8学习心得-- 逗号运算和逗号表达式,逻辑表达式,关系表达式
- VueJS表达式支持:逻辑控制或运算
- 从头认识Spring-1.15 对SpEl的值的操作(3)-逻辑运算以及条件表达式
- jsf EL 表达式逻辑操作运算
- 逻辑运算表达式&&或||
- javascript in运算符 真值和假值 赋值运算 表达式计算 delete运算符号 二十
- MATLAB-利用逻辑运算对当前矩阵状态一次更新-边界内部填充
- 利用STL 中的Stack 求逻辑表达式的值
- C++_利用栈进行运算符表达式的运算
- 利用VC设计简易逻辑表达式词法分析器
- C/C++计算器(利用栈表达式求值,支持函数运算)
- 使用双栈实现输出逻辑表达式的真值表
- 学习笔记---关系运算符、条件表达式、逻辑运算
- 利用数据库进行表达式运算
- zstu.4189: 逻辑运算(构建 && 前缀表达式入门)
- 警惕逻辑表达式中的无符号类型运算(C语言类型转换)
- 逻辑运算表达式(*=逻辑与,+=逻辑或,!=逻辑非)转化为二叉树
- 第六次作业——利用MFC实现计算器图形界面以及简单四则运算表达式批处理