问题 A: 数据结构作业02 -- 四则运算表达式计算

题目描述

计算非负整常数四则运算表达式,可用的运算符有:+ - * / ( ) 。

输入格式

一组非负整常数四则运算表达式,每个表达式输入一行,长度不超过1024个字符,每对括号内一定包含数字。

输出格式

每个表达式的计算结果输出一行,错误的表达式输出error。

输入样例

12+5
-4-7
3-*5
((12-3)/2)+5
3+7/(2-2)
 

输出样例  

17
error
error
9
error
 

数据范围与提示

算法流程:

E1:设立运算符栈和操作数栈;

E2:开始运算符#入栈,向表达式串尾添加结束运算符#;

E3:逐词读入表达式,并处理:

    E31:若读入为操作数,则入栈;

    E32:若读入为运算符,则与栈顶运算符相比较:

        E321:若栈顶运算符优先级高于读入运算符:
                     弹出栈顶运算符和两个操作数,计算并将结果入栈,执行步骤E32;

        E322:若栈顶运算符优先级低于读入运算符:
                     则将读入运算符入栈,执行步骤E3;

        E323:若栈顶运算符优先级等于读入运算符:
                     若为#,计算结束,若为括号,则弹出运算符,执行步骤E3。

E4:检查栈状态,得到计算结果;

代码展示 
核心思想:将中缀表达式转换成后缀表达式再进行运算。

注意:①若括号不能匹配,则表达式错误,所以先进行括号匹配判断。

           ②本代码存在的漏洞:用-1作为错误返回值,若计算结果也为-1,则无法分辨。因为楼主没改就通过了所以不改了,想要更完善,可以再加一点判断条件来区别。

#include<bits/stdc++.h>
#include<iostream>
#include<stack>
#include<string>
#include<cctype>
using namespace std;
//一点废话写在前面
//取名废,干脆给函数取名“没名字”了
//栈test一开始只是想test,没想到成了,名字就这样了
//为了各部分功能更明了,还是建议大家改成自己习惯的名字...

int noName(string org){
	int temp=0;
	stack<char>test;
	int num[100]={0};
	int index=0;
	char op[100];
	stack<int>number;

	int flag=0;
	for(int i=0;i<org.length();++i){
		char tp=org[i];//方便调试时查看当前处理字符
		if(isdigit(org[i])){
			temp*=10;
			temp+=org[i]-'0';
			flag=1;
		}
		else{
			if(flag){//正在拼写数字
				num[index]=temp;//数存入数字栈  atoi(temp.c_str())
				op[index]='!';
				index++;
				flag=0;
				temp=0;
			}
			if(org[i]=='#'){//读到末尾了
				while(!test.empty()){
					op[index++]=test.top();
					test.pop();
				}
				break;
			}
			else{//读到符号
				if(test.empty()||org[i]=='('){
					test.push(org[i]);
				}
				else if(org[i]==')'){//如果是右括号,出栈到左括号
					while(!test.empty() && test.top()!='('){
						op[index++]=test.top();
						test.pop();
					}
                    if(!test.empty())  test.pop();//弹出左括号
                    else  return -1;
				}
				else if(org[i]=='*'||org[i]=='/'){//如果是乘除,则乘除出栈,新符号入栈
					while(!test.empty() && (test.top()=='*'||test.top()=='/'))
					{
						op[index++]=test.top();
						test.pop();
					}
					test.push(org[i]);
				}
				else{//如果是加减
					while(!test.empty() && test.top()!='('){
						op[index++]=test.top();
						test.pop();
					}
					test.push(org[i]);
				}
			}	
		}
	}
	//后缀表达式求值
	int temp1=0;
	int temp2=0;
	for(int i=0;i<index;i++){
		if(op[i]=='!')//数字入栈
		{
			number.push(num[i]);
		}
		else{
			temp1=number.top();
			number.pop();
			if(number.empty())  return -1;
			temp2=number.top();
			number.pop();
			switch(op[i]){
				case '+':
					number.push(temp2+temp1);
					break;
				case '-':
					number.push(temp2-temp1);
					break;
				case '*':
					number.push(temp2*temp1);
					break;
				case '/':
					if(temp1==0)  return -1;//除0时error
					number.push(temp2/temp1);
					break;
			}
		}
	}
	return number.top();
}

int brackets(string org){//检查括号匹配情况
	int mark=0;
	for(int i=0;i<org.length();i++){
		if(org[i]=='(')  mark++;
		if(org[i]==')')  mark--;
	}
	return mark;
}

int main(){
	string org;
	while(cin>>org){
		if(brackets(org)){
			cout<<"error"<<endl;
		}
		else{
			org+='#';
			int result;
			result=noName(org);
			if(result==-1){
				cout<<"error"<<endl;
			}
			else  cout<<result<<endl;
			}
	}
	return 0;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值