数据结构与算法题目集(中文)7-21 求前缀表达式的值 (25分)

1.题目

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

输入格式:

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

输出格式:

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

输入样例:

+ + 2 * 3 - 7 4 / 8 4

输出样例:

13.0

2.题目分析

 1.计算方法:首先从右向左开始入栈,当遇到第一个操作符的时候出栈两次计算结果,再将结果入栈,最后输出总结果

坑:数字可能是小数或者负数!!!!!!!!!!!!

2.记住:输入时为反着的,要输出为正,类似这样的情况可以使用栈

3.atof使用#include<cstdlib>头节点  

4.getline(cin, list);//注意C++中一次输入一行的写法,该写法需要#include<string>头文件,但是会有换行符

3.代码

#include<iostream>
#include<stack>
#include<cstring>
#include<string>
#include<cstdio>
#include<cstdlib>//atof使用
using namespace std;
int main()
{
	stack<double>st;
	string list;
	getline(cin, list);//注意C++中一次输入一行的写法,该写法需要#include<string>头文件
	double answer=0;
	for (int i = list.length()-1; i >= 0; i--)//减一是因为getline会获取回车符
	{
		char aaa = list[i];
		answer = 0;
		stack<char>templist;//存放整个字符串
		bool isnotoperator = false;
		while ((list[i] != ' ')&&(isdigit(list[i])||list[i]=='.'))
		{
			isnotoperator = true;
			templist.push(list[i]);//将数字放入临时栈
			if (isdigit(list[i - 1]) || list[i - 1] == '.')//如果前面还有数字、小数点接着入栈
				i--;
			else
				break;

		}

		//char  number[31];
		//开始使用的是char数组,后来发现一个知名的错误就是数组使用完一次初始化的问题,若不做处理可能这次的数还有上次的残留,(70、4.5 5会残留)较麻烦
		string number;
		while (!templist.empty())
		{
			//number[d++]=templist.top();
			 number=number+ templist.top();
			templist.pop();//将数字转为string
		}
		if (isnotoperator)//如果上面经过了数字的转化计算,这里就将string转为double
		{
			double b = atof(number.c_str());
			if (list[i - 1] == '-'&&i>1)//如果前面为-,就改成负数
			{
				st.push(-b);//为负数
				i--;
			}
			else
				st.push(b);
		}
		if (list[i] != ' '&&!isdigit(list[i])&&isnotoperator==false)
		{
			double c, d;
			if (st.size() > 1)
			{
				 c = st.top(); st.pop();
				 d = st.top(); st.pop();
			}
			else//处理整个表达式只有一个数字的情况
			{
				if (list[i] == '+')//例如+9.2342342
				{
					c = st.top(); st.pop();
					d = 0;
				}
				else if (list[i] == '-')//例如-9.2342342
				{
					c = -1*st.top(); st.pop();
					d = 0;
				}
			}
			if (list[i] == '+')answer = answer + c + d;
			if (list[i] == '-')answer = answer + (c - d);
			if (list[i] == '*')answer = answer + (c*d);
			if (list[i] == '/')
			{
				if (d == 0) { cout << "ERROR" << endl; return 0; }//除数为0直接输出
				else answer = answer + (c / d);
			}
			st.push(answer);
		}
	}
	if(st.size()!=1)cout<< "ERROR" << endl;//防止整个式子不标准,不过好像没用 
	else printf("%.1f", st.top());
}
//+ + 2 * -20 - 7 4 / 8 4
//+ + -2.5 * 3.4 - 70 -4.5 / 8.3 4.2
//+123.434234











4.清爽明了版

(上面自己写的很恶心,参考https://blog.csdn.net/qq_41608020/article/details/80922359?utm_source=blogxgwz1

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
#include <string>
#include <cctype>
using namespace std;
stack <double> st;
int main()
{
	string s;
	getline(cin, s);
	for (int i = s.size() - 1; i >= 0; i--)
	{
		if (isdigit(s[i]))
		{
			double mul = 10, num = s[i] - '0';
			for (i--; i >= 0; i--)
			{
				if (isdigit(s[i]))
				{
					num += (s[i] - '0') * mul;
					mul *= 10;
				}
				else if (s[i] == '.')
				{
					num /= mul;
					mul = 1;
				}
				else if (s[i] == '-')
					num = -num;
				else
					break;
			}
			st.push(num);
		}
		else if (s[i] != ' ')   //else
		{
			double a, b, sum;
			a = st.top();
			st.pop();
			b = st.top();
			st.pop();
			switch (s[i])
			{
			case '+':
				sum = a + b;
				break;
			case '-':
				sum = a - b;
				break;
			case '*':
				sum = a * b;
				break;
			case '/':
			{
				if (b == 0)
				{
					cout << "ERROR";
					return 0;
				}
				sum = a / b;
			}
			}
			st.push(sum);
		}
	}
	printf("%.1lf", st.top());
}
发布了47 篇原创文章 · 获赞 1 · 访问量 441

猜你喜欢

转载自blog.csdn.net/qq_42325947/article/details/104219251