简单表达式求值 有人能帮我看看哪错了吗(更正:代码应该没错 是那个刷题网站脑子有问题了...莫名其妙一个例子它那里输出不了)

该文章介绍了如何使用C++实现一个程序,将输入的中序波兰式表达式转换为后序形式,并进行精确计算。程序处理包括整数和带有小数的浮点数,但遇到了某个用例未通过,作者确认代码本身没有问题,可能是输入或算法细节问题。
摘要由CSDN通过智能技术生成

题目是简单表达式求值(支持负数 小数)

 表达式中可能的运算符有+,-,*,/,()。
【输入】简单表达式
【输出】表达式的值

//输出的数据类型符合C/C++对表达式求值的定义,即表达式的输出类型由高精度的运算数来决定。

浮点型保留小数点后的3位小数

例如:
【输入】2*(4+5)-12
【输出】6
【输入】2*2.5
【输出】5.000

最后一个用例通不过

但我也不知道哪有问题 我试了的例子都对的

更正:那20个用例我自己试了都通得过 不是代码的问题(无语!!!!!!!!!!)

#include <iostream>
#include<stack>
using namespace std;
const int maxstack = 1000;

void trans(char arr[maxstack], char str[maxstack], bool& flag)//把中序波兰式转后序
{  // 1.数字 2.( 3.) 4.+-*/ 5.负号(表达式开头/括号后开头) 6..小数点(数字之后)

	stack<char> s1;//放字符
	stack<char> s2;//放数字 (最后全放s2中)
	int i = 0;
	//bool flag = false;//true--有小数 false--无小数
	if (arr[0] == '-')//表达式开头的负号
	{
		s2.push('0');
		s2.push('#');
		s1.push('-');
		i++;
	}
	while (arr[i] != '\0')
	{
		if (arr[i] >= '0' && arr[i] <= '9')//数字(数字串以#结尾)
		{
			s2.push(arr[i]);
			if ((!(arr[i + 1] >= '0' && arr[i + 1] <= '9')) && (arr[i + 1] != '.'))
				//到数字结尾了
			{
				s2.push('#');
			}
		}
		else if (arr[i] == '.')//.
		{
			s2.push(arr[i]);
			flag = true;//标记是小数
		}
		else if (arr[i] == '(')//(
		{
			s1.push(arr[i]);
			//(后面是-
			if (arr[i+1] == '-')
			{
				s2.push('0');
				s2.push('#');
				s1.push('-');
				i++;
			}
		}
		else if (arr[i] == '+' || arr[i] == '-' || arr[i] == '*' || arr[i] == '/')
			//+ - * / 
		{
			if (s1.empty())//空 -- 入栈s1
			{
				s1.push(arr[i]);
			}
			else
			{
				char item = s1.top();//s1栈顶运算符
				if (item == '(')
				{
					s1.push(arr[i]);//栈顶是( -- 入栈s1
				}
				else {//优先级+ = - < * = /
				空/栈顶是( -- 将arr[i]入栈s1
				//arr[i]优先级比item高-->将arr[i]入栈s1
				//否则-->将s1栈顶弹出 入栈s2 -->arr[i]再与新的s1栈顶比较
					switch (arr[i]) {
					case'+':
					case'-':
						while (!s1.empty() && item != '(')
						{
							s1.pop();
							s2.push(item);
							if (!s1.empty())
							{
								item = s1.top();
							}
							else
							{
								break;
							}
						}
						s1.push(arr[i]);
						break;
					case'*':
					case'/':
						if (item == '+' || item == '-')
						{
							s1.push(arr[i]);
						}
						else
						{
							while (!s1.empty() && item != '(' && item != '+' && item != '-')
							{
								s1.pop();
								s2.push(item);
								if (!s1.empty())
								{
									item = s1.top();
								}
								else
								{
									break;
								}
							}
							s1.push(arr[i]);
						}
						break;
					}
				}
			}
		}
		else if (arr[i] == ')')// )
		//依次弹出s1栈顶 压入s2 直到遇到)
		{
			char item = s1.top();
			while (item != '(')
			{
				s2.push(item);
				s1.pop();
				item = s1.top();
			}
			//此时s1栈顶为( --> 将()舍弃
			s1.pop();
		}
		i++;
	}
	
	while (!s1.empty())
	{
		char item = s1.top();
		s2.push(item);
		s1.pop();
	}//现在结果都在s2中

	//最后变成后序波兰式 放到str[maxstack]里
	int m = 0;
	stack<char> s3;
	while (!s2.empty())
	{
		char item = s2.top();
		s3.push(item);
		s2.pop();
	}
	while (!s3.empty())
	{
		str[m] = s3.top();
		s3.pop();
		m++;
	}
	str[m] = '\0';
	
}

void count_value(char str[maxstack], bool flag)//后序波兰式的数组
{
	stack<double> s;//放数字
	int i = 0;
	bool outcome = true;
	double x = 0;
	double y = 0;
	while (str[i] != '\0')
	{
		if (str[i] >= '0' && str[i] <= '9')//数字--结尾是#
		{
			int number1[maxstack] = { 0 };
			int j = 0;
			int number2[maxstack] = { 0 };
			int k = 0;
			while (str[i] != '#')
			{
				if (str[i] >= '0' && str[i] <= '9')
				{
					number1[j] = str[i] - '0';
					i++;
					j++;
				}
				else if (str[i] == '.')//小数点
				{
					i++;
					while (str[i] >= '0' && str[i] <= '9')
					{
						number2[k] = str[i] - '0';
						i++;
						k++;
					}
				}
			}

			double ret1 = 0;
			double pow1 = 1;
			for (int m = j - 1; m >= 0; m--)
			{
				ret1 += pow1 * number1[m];
				pow1 *= 10;
			}
			//ret1=小数点前的数值

			double ret2 = 0;
			double pow2 = 0.1;
			for (int m = 0; m < k; m++)
			{
				ret2 += pow2 * number2[m];
				pow2 *= 0.1;
			}
			//ret2=小数点后的数值
			s.push(ret1 + ret2);//把这个小数入栈 
		}
		else if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/')
		{
			if (!s.empty())
			{
				x = s.top();
				s.pop();
				if (!s.empty())
				{
					y = s.top();
					s.pop();
				}
				else {
					outcome = false;
				}
			}
			else {
				outcome = false;
			}
			switch (str[i])
			{
			case '+':
				s.push(y + x);
				break;
			case '-':
				s.push(y - x);
				break;
			case '*':
				s.push(y * x);
				break;
			case '/':
				s.push(y / x);
				break;
			default:
				outcome = false;
				break;
			}
		}
		i++;
	}
	if (outcome)
	{
		if (!s.empty())
		{
			double key;
			key = s.top();
			s.pop();
			if (s.empty())
			{
				if (flag)//输出小数
					printf("%.3f", key);
				else
				{
					int intkey = key;
					printf("%d", intkey);
				}
			}
			else { cout << "输入不合法"; }
		}
		else { cout << "输入不合法"; }
	}
	else
	{
		cout << "输入不合法";
	}
}


int main()
{
	char arr[maxstack];
	int i = 0;
	arr[i] = cin.get();
	while (arr[i] != '\n')
	{
		i++;
		arr[i] = cin.get();
	}
	arr[i] = '\0';//把输入的都放数组中

	char str[maxstack];
	bool flag = false;//true--有小数 false--无小数

	trans(arr, str, flag);//把中序波兰式转后序

	count_value(str, flag);//后序波兰式求值

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值