程序设计与算法MOOC慕课005:Boolean Expressions(递归)

题目

给定一个逻辑运算表达式,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里,然后直接把所有空格都去除,免得后面递归里还要考虑空格的情况。

猜你喜欢

转载自blog.csdn.net/weixin_43390123/article/details/117108407