[C++]数据结构实验04:使用堆栈进行简单的四则运算

来源:互联网 发布:豪气的诗句 知乎 编辑:程序博客网 时间:2024/04/29 14:27
/************************************************************************************//*  实验04:堆栈的应用/*1.输入一个数学表达式(假定表达式输入格式合法),计算表达式结果并输出。/*2.数学表达式由单个数字和运算符“+”、“-”、“*”、“/”、“(、) ”构成,/*  例如 2 + 3 * ( 4 + 5 ) – 6 / 4/************************************************************************************///自定义链表形式的堆栈#include<iostream>#include<string>using namespace std;template<class T>class Node{public:T data;Node<T> *link;};template<class T>class LinkedStack{public:LinkedStack(){topNode=0;}~LinkedStack();bool IsEmpty()const{return topNode==0;}bool IsFull()const;T Top()const;LinkedStack<T>& PushStack(const T&x);LinkedStack<T>& PopStack(T&x);LinkedStack<T>& PopStack();Node<T> *topNode;void Show()const;int Size()const;};//处理数组越界的报错class OutOfBounds{        public:            OutOfBounds(){            cout<<"Out Of Bounds!"<<endl;            }    };        //内存不足的异常类    class NoMem{        public:            NoMem(){                cout<<"No Memory!"<<endl;            }    };    //使new引发NoMem异常而不是xalloc异常    //如果要恢复原始行为可以做以下调用    //_set_new_handler(Old_Handler);    int my_new_handler(size_t size){        throw NoMem();    }     //打印出堆栈中的所有元素template<class T>void LinkedStack<T>::Show()const{  Node<T> *current = topNode;while(current) {        cout<<current->data<<endl;  current=current->link;    }  }    //堆栈的析构方法template<class T>LinkedStack<T>::~LinkedStack(){Node<T>*next;while(topNode){next=topNode->link;delete topNode;topNode=next;}}//判断当前堆栈是否为空template<class T>bool LinkedStack<T>::IsFull()const{try{Node<T>*p = new Node<T>;delete p ;return false;}catch(NoMem){return true;}}//返回当前堆栈的长度template<class T>int LinkedStack<T>::Size()const{int count = 0;Node<T> *current = topNode;while(current) {count++;       current=current->link;    }  return count;}//获取堆栈顶部的元素template<class T>T LinkedStack<T>::Top()const{if(IsEmpty())throw OutOfBounds();return topNode->data;}//将元素x压入堆栈template<class T>LinkedStack<T>& LinkedStack<T>::PushStack(const T&x){Node<T>*p = new Node<T>;p->data = x;p->link = topNode;topNode = p;return *this;}//删除栈顶元素并将其送入xtemplate<class T>LinkedStack<T>&LinkedStack<T>::PopStack(T&x){if(IsEmpty())throw OutOfBounds();x=topNode->data;Node<T>*p = topNode ;topNode = topNode->link;delete p;return *this;}//删除栈顶元素并将其送入xtemplate<class T>LinkedStack<T>&LinkedStack<T>::PopStack(){if(IsEmpty())throw OutOfBounds();Node<T>*p = topNode ;topNode = topNode->link;delete p;return *this;}int Level(char m){//算符号优先级switch (m){case '+':case '-':return 1;case '*':case '/':return 2;case '(':case ')':return 0;case '#':    return -1;}return -2;}void main(){cout<<"Input"<<endl;LinkedStack<char>y;//运算符堆栈LinkedStack<double>x;//int 堆栈string s=" ";//接受算式表达式string ss;//复制s    string l=" ";//用于存像"123"的字符串cin>>s;ss=s;s+="#$";//#将y中的运算符都拿出来,$用于表示算式结尾int i=0;//s的下标偏移量double c=0;//存中间运算结果bool m=1;//判断表达式是否正确,这里只做了简单判断while(s[i]!='$')//对表达式逐个字符扫过去{    //往栈x中放int数if(s[i]>47&&s[i]<58){//字符0-9的ASCII范围为47-58l+=s[i];for(int j=i+1;s[j]>47&&s[j]<58;j++)l+=s[j];x.PushStack(atof(l.c_str()));//将类似“123”字符串换成int型压入栈中;l=" ";i=j;}//对符号进行操作if(s[i]>=35&&s[i]<=47){//35-47是一段符号的ASCII区间,主要用于捕获符号if(y.Size()==0||s[i]=='('||Level(s[i])>Level(y.Top()))y.PushStack(s[i]);else{if(s[i]==')'){//遇到')'的情况,直接将y中的符号一个一个拿出来运算,直到遇到'('为止for(;y.Top()!='(';y.PopStack()){char d=y.Top();      //取栈顶的一个元素double a=x.Top();       //将栈顶元素删除掉x.PopStack();double b=x.Top();x.PopStack();switch(d){case '+':c=a+b;break;case '-':c=b-a;break;case '*':c=a*b;break;case '/':c=b/a;break;default:break;}x.PushStack(c);          //中间结果放入x中}y.PopStack();               //将‘('弹出栈x}else{                      //遇到+,-,*,/的处理for(;y.Size()!=0&&Level(s[i])<=Level(y.Top());y.PopStack()){//将y里不小于当前符号优先级的符号拿出来,运算char d=y.Top();double a=x.Top();x.PopStack();double b=x.Top();x.PopStack();switch(d){case '+':{c=a+b;break;}case '-':{c=b-a;break;}case '*':{c=a*b;break;}case '/':{c=b/a;break;}default:break;}//end of switchx.PushStack(c);}//end of fory.PushStack(s[i]);//将当前符号放入y}}//end of else*/i++;}else{//35-58 ASCII外的其他符号报错*************************cout<<"出现"<<s[i]<<"表达式不正确";m=0;break;}}//end of whilecout<<"Output"<<endl;if(m)cout<<ss<<"="<<x.Top();cout<<endl;cout<<"End"<<endl;}
原创粉丝点击