第7-8周练习2020——3-8 求前缀、中缀表达式的值 (20分)

目录

前缀

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。

输入格式:
输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、/以及运算数,不同对象(运算数、运算符号)之间以空格分隔。

输出格式:
输出前缀表达式的运算结果,保留小数点后1位,或错误信息ERROR。

输入样例:

+ + 2 * 3 - 7 4 / 8 4

输出样例:

13.0

思路
之前做过的中缀表达式转换成后缀表达式线性结构实验题目集2020——1-3 表达式转换 (25分)
emmmmm把前缀倒过来看就是后缀,我以为前缀照着做做就能写出来的结果依然不行,唉,太难了
下面是百度的代码
函数atof()是C 语言标准库中的一个字符串处理函数,功能是把字符串转换成浮点数,所使用的头文件为<stdlib.h>。语法格式为:double atof(const char *nptr)。
string ss;
double x=atof(ss.c_str());
代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    double a,b;
    int flag=0;
    string s[100];//规定一百个字符串数组
    int n=0;
    while(cin>>s[n++]);//输入中空格是截止符
    n--;
    stack<double> num;
    for(int i=n-1;i>=0;i--){
            /*如果是运算符*/
        if((s[i][0]=='+'||s[i][0]=='-'||s[i][0]=='*'||s[i][0]=='/')&&s[i].length()==1){
            if(num.size()<2){ flag=1;break;}
            a=num.top(); num.pop();
            b=num.top(); num.pop();
            if(s[i][0]=='*') num.push(a*b);
            else if(s[i][0]=='/') {
                    if(b==0) {flag=1;break;}
                    num.push(a/b);
            }
            else if(s[i][0]=='+') num.push(a+b);
            else if(s[i][0]=='-') num.push(a-b);
        }
        else{/*为数*/
            double x=atof(s[i].c_str());
            num.push(x);
        }
    }
    if(num.size()!=1) flag=1;
    if(flag) cout<<"ERROR";
    else printf("%.1f",num.top());
    return 0;
}

中缀

给定一个表达式,其中运算符仅包含 +,-,*,/(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。

注意:

数据保证给定的表达式合法。
题目保证符号 - 只作为减号出现,不会作为负号出现,例如,-1+2,(2+2)*(-(1+1)+2) 之类表达式均不会出现。
题目保证表达式中所有数字均为正整数。
题目保证表达式在中间计算过程以及结果中,均不超过 231−1。
题目中的整除是指向 0 取整,也就是说对于大于 0 的结果向下取整,例如 5/3=1,对于小于 0 的结果向上取整,例如 5/(1−4)=−1。
C++和Java中的整除默认是向零取整;Python中的整除//默认向下取整,因此Python的eval()函数中的整除也是向下取整,在本题中不能直接使用。
输入格式
共一行,为给定表达式。
输出格式
共一行,为表达式的结果。
数据范围
表达式的长度不超过 105。
输入样例:

(2+2)*(1+1)

输出样例:

8

代码

#include<bits/stdc++.h>

using namespace std;

const int N=1e5+5;
int s[N],idx=0;
stack<int> num;
stack<char> op;
void eval(){
		int a=num.top();num.pop();
		int b=num.top();num.pop();
		if(op.top()=='+') num.push(a+b);
		else if(op.top()=='-') num.push(b-a);
		else if(op.top()=='*') num.push(a*b);
		else if(op.top()=='/') num.push(b/a);
		op.pop();
}
int main(){
	unordered_map<char,int> mp{{'+',1},{'-',1},{'*',2},{'/',2}};
	string s;
	
	cin>>s;
	for(int i=0;i<s.size();i++){
		if(isdigit(s[i])){
			int x=0,j=i;
			while(j<s.size()&&isdigit(s[j]))
				x=x*10+s[j++]-'0';
			i=j-1;
			num.push(x);
		}
		else{
			if(s[i]=='(') op.push(s[i]);
			else if(s[i]==')'){
				while(op.top()!='(') eval();
				op.pop();
			}
			else{
				while(op.size()&&mp[op.top()]>=mp[s[i]]) eval();
				op.push(s[i]);
			}
		}
		
	}
	while(op.size()) eval();
	cout<<num.top();
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值