温存温存6

一、实验目的
1、 掌握栈结构的定义与实现;
2、 掌握栈结构的使用。
二、实验内容
1、题目描述:
创建栈类,采用数组描述;计算数学表达式的值。 输入数学表达式,输出表达式的计算结果。数学表达式由单个数字和运算符“+”、“-”、“”、“/”、“(”、“) ”构成,例如 2+3(4+5)–6/4。
输入输出格式:
输入:
第一行一个整数n(1<=n<=100),代表表达式的个数。
接下来n行,每行一个表达式,保证表达式内的数字为单个整数,表达式内各运算符和数字间没有空格,且表达式的长度不超过2000。
输出:
每行表达式输出一个浮点数,要求保留两位小数,保证输入表达式合法。

#include<iostream>
#include<string>
#include<iomanip>
using namespace std;
template<class T>
void changelength(T *a,int oldlength,int newlength){
    
    
	T* temp=new T[newlength];
	int number=newlength<oldlength?newlength:oldlength;
	for(int i=0;i<number;i++){
    
    
		temp[i]=a[i];
	}
	delete []a;
	a=temp;
}
template<class T>
class arrayStack{
    
    
	private:
		int stackTop;//栈顶 
		int arrayLength;//容量
		T *stack;//元素数组 
	public:
		arrayStack(int initialCapacity=10);
		~arrayStack(){
    
    delete []stack;}
		bool empty() const {
    
    return stackTop==-1;}
		int size() const{
    
    return stackTop+1;}
		T&top(){
    
    
			if(stackTop==-1)
				cout<<"empty";
			return stack[stackTop];
		} 
		void pop();
		void push(const T&theElement);
};
template<class T>
arrayStack<T>::arrayStack(int inintialCapacity){
    
    
	if(inintialCapacity<1){
    
    
		cout<<"must be >1";
		exit(0); 
	}
	arrayLength=inintialCapacity;
	stack=new T[arrayLength];
	stackTop=-1;
} 
template<class T>
void arrayStack<T>::pop(){
    
    
	if(stackTop==-1)
		cout<<"empty";
	stack[stackTop--].~T(); 
}
template<class T>
void arrayStack<T>::push(const T&theElement){
    
    
	if(stackTop==arrayLength-1){
    
    
		changelength(stack,arrayLength,2*arrayLength);
		arrayLength=2*arrayLength;
	}
	stack[++stackTop]=theElement;
}
void calculate(arrayStack<double> &n, arrayStack<char> &c){
    
    
//定义运算,将数字栈的前两个数和符号栈栈顶元素取出做一次运算 并将结果压入数字栈 
	if(c.top()=='(') return;
	double a,b;
	a=n.top();    
	n.pop();             //弹出栈顶元素 
	b=n.top();    
	n.pop();             //弹出栈顶元素 
	switch(c.top()){
    
         //根据符号栈的栈顶元素不同进行不同运算 
		case '+':
			n.push(a+b);
			break;
		case '-':
			n.push(b-a);
			break;
		case '*':
			n.push(a*b);
			break;
		case '/':
			n.push(b/a);
			break;	
		default:break;
	}
	c.pop();//将运算完的符号弹出栈 
}
void operate(string s,int length) {
    
    
	bool tag=false;      //用来判断输入-的是否为负号 
	arrayStack<double> n(length);     //声明一个数字栈 
	arrayStack<char> c(length);       //声明一个字符栈 
		for(int i=0;i<length;i++){
    
        //遍历输入的表达式 
		if(s[i]==' ') continue;       //如果输入的如果是空格,跳过 
		if(s[i]>='0'&&s[i]<='9'){
    
          //当输入为数字时 
			int k=s[i]-'0';
			while(s[i+1]>='0'&&s[i+1]<='9'){
    
    //如果下一个为数字 则记录整个数字
				k=10*k+(s[i+1]-'0');
				i++;
			}
			if(tag){
    
                    //判断是否为负数  
				k=-k;
				tag=false;          //读到一个负数,标识符归零 
			}
			n.push(k);               //将读入的数字压到数字栈 
		}else{
    
    //读到的是字符 
			if((i==0||s[i-1]=='(')&&s[i]=='-'){
    
    //-号前面为(或者-号为第一个代表-为负号而不是减号 
				tag=true;
				continue;
			}
			switch(s[i]){
    
    
				case '+':
				case '-':
					if(c.empty()||c.top()=='(') c.push(s[i]);//如果符号栈为空或者栈顶元素为(,+、-直接压入栈 
					else{
    
    
						calculate(n,c);                      //+-运算符优先级最低,对之前运算先运算 
						if(!c.empty()&&c.top()!='(') calculate(n,c);
						c.push(s[i]);                        //将读到的符号压入栈 
					}
					break;
				case '*':
				case '/':
					if(c.empty()||c.top()=='(') c.push(s[i]);//如果符号栈为空或者栈顶元素为(,*/直接压入栈 
					else if(c.top()=='+'||c.top()=='-') c.push(s[i]);//如果前一个运算符为+或-,*/直接压入栈 
					else if(c.top()=='*'||c.top()=='/'){
    
    //前一个运算符为*或/可以直接运算                                 
							calculate(n,c);
							c.push(s[i]);
						 } 				
					break;
				case '('://左括号直接入栈 
					c.push(s[i]);
					break;
				case ')'://遇到右括号 ,对括号内运算直至运算到左括号 
					while (c.top()!='(') {
    
    
					calculate(n,c);
					}
					c.pop();//将左括号弹出栈 
					break;
				default:break;
			}
		}
	} 
	while(!c.empty()) calculate(n,c);
			cout<<setprecision(2)<<fixed<<n.top()<<endl;
}
int main()
{
    
      
	int n;
	cin>>n;
    for(int i=0;i<n;i++){
    
    
		string s;             //将输入的表达式存到一个字符串中 
		int length;           //记录字符串长度  
		cin>>s;               //输入表达式 
		length=s.length();	
	    operate(s,length);
	} 
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/m0_51406030/article/details/121166230
6