后缀表达式的计算(c++代码实现)

使用栈对数据进行存放

读取到操作符时取栈顶的两位数进行计算

其中数据包括负数,小数等

思路如下:

对于一个浮点数,分别用x1储存整数位,x2储存小数位,同时对小数位数进行计数,在读完一个浮点数时,对x2进行处理使其变为小数,然后与x1相加压入数栈中。

对于负数,由于负数前的负号与操作符的负号有混淆,因此在遇到负号时,先不进行任何操作,在读到下一个字符时,如果下一个字符是空格,则对数栈进行一次运算,如果下一个字符是操作数,则将其标记为负数,在压栈时加上符号。

对于不同的操作符,除减号外其余正常读到便进行计算。

对于空格,有两种情况,第一种是前面是一个浮点数,这时要进行压栈,但也存在空格前是操作符的情况,因此要使用一个变量判断空格前的上一个有效字符是否为操作符,并以此为根据决定是否对x1+x2压栈。

在实现时,在遇到前一个有效位为操作符的空格时要将表示前一位为操作符的变量清零,这样下一个数才能正常压栈。

在while循环结束后,有一种极端可能是最后的操作符为减号,但由于我们的程序在遇到减号时会“延缓处理”,因此在while循环外应再次判断是否需要再执行一次减法操作,否则将会使答案出现错误。

最后根据想要的精度使用头文件中的<iomanip>的setprecision(n)为输出设定保留n位小数

#include<stack>
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
	stack<double> a;
	char s[100];
	cin.getline(s,100);
	int i=0;
	double x1=0;//暂存整数位;
	double x2=0;//暂存小数位;
	bool isop=0;//上一个有效的字符为操作符;
	bool fh=0;//出现符号; 
	bool isxs=0;//是否为小数;
	bool isfs=0;//是否为负数;
	int  index=0;//小数位数; 
	while(s[i]!='\0')
	{
		int len=a.size();
		if(s[i]=='.'){
			isxs=1;
			i++;
			continue;
		} 
		if(s[i]=='-')
		{
			fh=1;
			isfs=1;
		}
		
		if(isxs==0&&s[i]>='0'&&s[i]<='9'){
			x1=x1*10+s[i]-'0';
			i++;
			continue;
		}//读整数位 ; 
		if(isxs==1&&s[i]>='0'&&s[i]<='9'){
			x2=x2*10+s[i]-'0'; 
			index++;
			i++;
			continue;
		}//读小数位; 
		if(s[i]==' '&&!isop){
			if(isfs){
				for(int i=0;i<index;i++)x2/=10;
				a.push(-(x1+x2));
				index=x1=x2=0;
				isxs=0;
				isfs=0; 
				isop=0;
				fh=0;
			}
			else{
				for(int i=0;i<index;i++)x2/=10;
				a.push(x1+x2);
				index=x1=x2=0;
				isxs=0;
				isop=0;
			}
			i++;
			continue;
		}
		if(s[i]==' '&&isop){
			isop=0;
		}
		if(s[i]==' '&&fh){
			isfs=0;
			fh=0;
			double k;
			k=a.top();
			a.pop();
			a.push(a.top()-k);
			a.pop();
				
		}
		if(s[i]=='+'||s[i]=='*'||s[i]=='/'){
			isop=1;
			switch(s[i])
			{
				case '+':
					{
						double k2,k1;
			k2=a.top();
			a.pop();
			k1=a.top();
			a.pop();
			a.push(k1+k2);
						break;
					}
				case '*':
					{
						double k2,k1;
			k2=a.top();
			a.pop();
			k1=a.top();
			a.pop();
			a.push(k1*k2);
						break;
					}
				case '/':
					{
						double k2,k1;
			k2=a.top();
			a.pop();
			k1=a.top();
			a.pop();
			a.push(k1/k2);
						break;
					}
			}
			i++;
			continue;
		}
		i++;
	}
	if(fh){
		double k2,k1;
			k2=a.top();
			 int len1=a.size();
			a.pop();
			len1=a.size();
			k1=a.top();
			len1=a.size();
			a.pop();
			 len1=a.size();
			a.push(k1-k2);
			 len1=a.size();
			
	}
	
	cout<<fixed<<setprecision(2)<<a.top()<<endl;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值