📄 main.cpp
字号:
#include<iostream>
#include<math.h>
#include <string>
#include <cstdlib>
#include<ctype.h>
using namespace std;
const int SIZE=20;
template <class T> class Queue;
template <class T> class SeqQueue;
enum ResultCode{Underflow,Overflow,Success,Duplicate,NotPresent,Inputwrong};
bool IsNumber(const char *s){
bool Numberdoor=0,Indexdoor=0,NePositivedoor=0;
bool Decimaldoor=0;
int i=0;
char c;
while(*(s+i)!='\0'){
c=*(s+i);
if(isdigit(c)) {
Numberdoor=1;
NePositivedoor=1;
}
else if(c=='.'){
if(Decimaldoor==1) return false;
Numberdoor=0;
Decimaldoor=1;
}
else if(c=='+'||c=='-'){
if(NePositivedoor==1) return false;
if(Numberdoor==1) return false;
NePositivedoor=1;
Numberdoor=0;
}
else if(c=='e'||c=='E'){
if(Indexdoor==1) return false;
if(Numberdoor==0) return false;
Indexdoor=1;
Numberdoor=0;
NePositivedoor=0;
Decimaldoor=1;
}
else return false;
i++;
}
if(Numberdoor==0) return false;
return true;
}
int icp(const char *c)
{ // 计算运算符c的栈外优先级
int priority;
switch(c[0]){
case '(': priority=8; break;
case ')': priority=1;break;
case '+':
case '-': priority=2; break;
case '*':
case '/': priority=4; break;
case '^': priority=6; break;
case '#': priority=0; break;
}
return priority;
}
int isp(const char *c)
{ // 计算运算符c的栈内优先级
int priority;
switch(c[0]){
case '(': priority=1; break;
case ')': priority=8; break;
case '+':
case '-': priority=3; break;
case '*':
case '/': priority=5; break;
case '^': priority=7; break;
case '#': priority=0; break;
}
return priority;
}
bool OperateSymbol(const char *c){
switch(*c){
case '+':
case '-':
case '*':
case '^':
case '(':
case '/':
return true;
default: return false;
}
}
template <class T>
class Queue
{
public:
virtual bool IsEmpty() const=0;
virtual bool IsFull() const=0;
virtual bool Front(T &x) const =0;
virtual bool EnQueue(T x) =0;
virtual bool DeQueue()=0;
virtual bool Clear() =0;
};
template <class T>
class SeqQueue:public Queue<T>
{
private:
int front, rear;
int maxSize;
T *q;
public:
SeqQueue(int mSize);
~SeqQueue(){delete []q;}//释放内还
bool IsEmpty() const{return front==rear;}
bool IsFull() const {return (rear+1)% maxSize==front;}
bool Front(T &x) const;
bool EnQueue(T x);
bool DeQueue();
bool Clear() {front=rear=0; return true;}
void ListAll();
T IDfind(int i);
};
void InfixToPostfix(SeqQueue<string> &suffix0);
template <class T>
SeqQueue<T>::SeqQueue(int mSize){
maxSize=mSize;
q=new T[maxSize];
front=rear=0;
}
template <class T>
bool SeqQueue<T>::Front (T &x) const{
if (IsEmpty()){
cout<<"empty"<<endl; return false;//空队列处理
}
x=q[(front+1)%maxSize];
return true;
}
template <class T>
bool SeqQueue<T>::EnQueue (T x){
if (IsFull()){//溢出处理
cout<<"队满"<<endl; return false;
}
q[(rear=(rear+1)%maxSize)]=x;
return true;
}
template <class T>
bool SeqQueue<T>::DeQueue (){
if(IsEmpty()){//空队列处理
cout<<"队列下溢"<<endl; return false;
}
front=(front+1)%maxSize;
return true;
}
template <class T>
void SeqQueue<T>::ListAll (){//输出队列里的所有元素
int temp;
int number=0;
temp=front;
if(front==rear) {cout<<"队列无数据 !"<<endl;return;}
do{ cout<<q[temp+1]<<' ';
temp=(temp+1)%maxSize;
}while(rear!=temp+1);
}
template <class T>
T SeqQueue<T>::IDfind(int i){//根据在队列里的序号找出相应元素
int number=front;
if(i==0) return q[front+1];
number=(number+1+i)%maxSize;
return q[number];
}
//将中缀表达式转化为后缀表达式
template <class T>
class stack
{ public:
virtual bool IsEmpty() const=0;
virtual bool IsFull() const=0;
virtual bool Top(T &x) const=0;
virtual bool Push(T x)=0;
virtual bool Pop()=0;
virtual void Clear()=0;
};
template <class T>
class seqstack:public stack<T>
{
public:
seqstack(int mSize);
~seqstack(){delete []s;}
bool IsEmpty() const {return top==-1;}
bool IsFull() const {return top==maxTop;}
bool Top(T &x) const;//取出栈顶元素
bool Push(T x);//压入栈
void Clear(){top=-1;}//清空栈
bool Pop();//弹出栈
private:
int top;//栈顶指针
int maxTop;//最大栈顶指针
T *s;
};
template <class T>
seqstack<T>::seqstack(int mSize)//初始化栈
{
maxTop=mSize-1;
s=new T[mSize];
top=-1;
}
template <class T>
bool seqstack<T>::Top(T &x) const
{
if(IsEmpty()){
cout<<"栈空"<<endl;return false;
}
x=s[top];return true;
}
template <class T>
bool seqstack<T>::Push(T x)
{
if(IsFull()){
cout<<"栈上溢"<<endl;return false;
}
s[++top]=x;return true;
}
template <class T>
bool seqstack<T>::Pop()
{
if(IsEmpty()){
cout<<"栈下溢"<<endl;return false;
}
top--;return true;
}
//定义计算器类
class Calculator
{
public:
Calculator(int maxSize):s(maxSize),suffix(maxSize) {};
void Run();//从队列逐个读入字符,做相应的运算,输出结果
void Clear(){s.Clear();suffix.Clear();}
private:
SeqQueue<string> suffix;//存放转换后得到的后缀表达式队列对象
seqstack <double> s;//声明存放操作数的栈对象
void PushOperand(double);//操作数进栈
bool GetOperands(double &,double &);//从栈中弹出2个操作数
bool DoOperator(const char *per);
};
void Calculator::PushOperand(double op)
{
s.Push(op);
}
bool Calculator::GetOperands(double &op1,double &op2)
{
if(!s.Top(op1)){
cerr<<"操作符多余"<<endl;return false;
}
s.Pop();
if(!s.Top(op2)){
cerr<<"操作符多余"<<endl;return false;
}
s.Pop(); return true;
}
bool Calculator::DoOperator(const char *oper)
{
bool result;
double oper1,oper2;
result=GetOperands(oper1,oper2);//从栈中弹出2个操作数
if(result){
switch(*oper)
//根据操作符做相应的运算,先出栈的操作数oper1
//放在操作符的右边,后出栈的oper2放在左边
{
case '+':s.Push(oper2+oper1);break;
case '-':s.Push(oper2-oper1);break;
case '*':s.Push(oper2*oper1);break;
case '/':if (fabs(oper1)<1e-6){//如果分母为0,则做出错处理
cerr<<"Divide by 0!"<<endl;
Clear();return false;
}
else s.Push(oper2/oper1);break;
case '^':s.Push(pow(oper2,oper1));break;
}
return true;
}
else {Clear();return false;}
}
void Calculator::Run()
{
const char * c;double newop;
cout<<"请输入运算式!"<<endl;
InfixToPostfix(suffix);//中缀转换为后缀
int i=0;
while(suffix.IDfind(i)!="="){//从队列中依次读入一个字符,遇'#'结束
c=suffix.IDfind(i).c_str();
i++;
switch(*c){//从读入的字符做如下处理
case '+':
case '-':
if(strlen(c)>1){
newop=atof(c);
PushOperand(newop);
}
else {if(DoOperator(c)==0) return;}
break;
case '*':
case '/':
case '^':if(DoOperator(c)==0) return;break;//是操作符则进行相应的计算
default://如不是操作符,则转换为操作数
newop=atof(c);
PushOperand(newop);break;//操作数进栈
}
}
if(s.Top(newop)){
s.Pop();
if(s.IsEmpty ()==1){
cout<<"结果是:"<<newop<<endl;}//取到栈顶元素,并输出结果
else cout<<"操作数多余"<<endl;
Clear();
}
}
void InfixToPostfix(SeqQueue<string> &suffix0){
seqstack<string> s(SIZE);
string ch, y;
s.Push("=");
while(cin>>ch,ch!="="){
if(IsNumber(ch.c_str())) suffix0.EnQueue (ch);//扫描到操作数直接入队
else if(ch==")") //扫描到右括号时的处理
for(s.Top(y),s.Pop();y!="(";s.Top(y),s.Pop())
suffix0.EnQueue (y);
else if(OperateSymbol(ch.c_str())) {//扫描到其他操作符时的处理
for(s.Top(y),s.Pop();icp(ch.c_str())<=isp(y.c_str());s.Top(y),s.Pop()){
suffix0.EnQueue (y);}//则弹出的m栈顶操作符优先级高时入队
s.Push(y);//当弹出的栈顶操作符的优先级低时, 将其重新压回栈中
s.Push(ch);//然后扫描到的操作符进栈
}
else {
cout<<"你输错"<<ch<<endl;
s.Clear();
suffix0.Clear();
exit(1);
}
}
while(!s.IsEmpty()){
s.Top(y); s.Pop();
if(y!="=") suffix0.EnQueue (y);
}
suffix0.EnQueue ("=");
}
void main()
{char c;
cout<<" 欢迎使用本计算系统(笑^_^)"<<endl;
cout<<" 注意 1.=表示算术式结束标志符!!!"<<endl;
cout<<" 2.数字和符号之间用空格隔开"<<endl;
Calculator Cal(SIZE);
do{
Cal.Run();
cout<<"请输入组合键Ctrl+Z,再按回车结束,按其他键继续!!!"<<endl;
c=cin.get();
}while((c=cin.get())!=EOF);
cout<<"谢谢使用...."<<endl;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -