题目
给定一个逻辑运算表达式,V代表true,F代表false,对其进行与或非运算,输出最终结果。
运算时!的优先级最高,&其次,|最低。
输入为多行输入,每个表达式占一行。表达式中会有随机的空格。
样例输入
( V | V ) & F & ( F| V)
!V | V & V & !F & (F | V ) & (!F | F | !V & V)
(F&F|V|!V&!F&!(F|F&V))
样例输出
Expression 1: F
Expression 2: V
Expression 3: V
解题思路
这个题跟老师慕课里讲的加减乘除表达式计算非常相似,其实按照老师讲的表达式、项、因子来划分反而不太好理解,他并没有提运算优先级的事。但这道题的关键就是层层嵌套,运算优先级高的在最里层。
在加减乘除中,加减是同一等级,放在最外层;乘除放在加减里面;括号和数字放在乘除里面。
在这道题中,|优先级最低放在最外层;&放在|里面;括号和!放在&里面。
代码:
#include <iostream>
#include <string>
using namespace std;
int i = 1, n = 0;
string exps; //存储读入的表达式
int sz; //表达式的长度
bool boolean(char c) //把V和F转化成布尔值
{
if (c == 'V') return true;
else return false;
}
void nospace(string &s) //去除空格
{
auto it = s.begin();
while (it != s.end()) {
if (isspace(*it))
it = s.erase(it);
else ++it;
}
}
//三层函数
bool or_value();
bool and_value();
bool term_value();
int main()
{
while (getline(cin, exps)) {
nospace(exps);
sz = exps.size();
n = 0; //每处理完一行把n置零
if (or_value()) {
cout << "Expression " << i++ << ": V" << endl;
}
else {
cout << "Expression " << i++ << ": F" << endl;
}
}
return 0;
}
bool or_value() //这三段程序可以说跟老师讲的表达式的代码一模一样
{
bool result = and_value();
bool more = true;
while (more) {
char c = 'a'; //随便初始化一下,只要别是&!|()就行
if(n<sz) c = exps[n];
if (c == '|') {
++n;
bool value = and_value();
result = result || value;
}
else more = false;
}
return result;
}
bool and_value()
{
bool result = term_value();
bool more = true;
while (more) {
char c = 'a';
if (n < sz) c = exps[n];
if (c == '&') {
++n;
bool value = term_value();
result = value && result;
}
else more = false;
}
return result;
}
bool term_value()
{
bool result = true;
char c = 'a';
if (n < sz) c = exps[n];
if (c == '(') {
++n;
result = or_value();
++n;
}
else if (c == '!') {
++n;
result = !term_value(); //!后面调用的依然是最高优先级的这层,仔细体会
}
else {
result = boolean(c);
++n;
}
return result;
}
因为数据有很多行,这里我用getline把一行读到了一个string里,然后直接把所有空格都去除,免得后面递归里还要考虑空格的情况。