C++表达式求值
操作符符号栈优先级
| 操作符ch | # | ( | *,/,% | +,- | ) |
|---|---|---|---|---|---|
| isp(栈内) | 0 | 1 | 5 | 3 | 6 |
| icp(栈外) | 0 | 6 | 4 | 2 | 1 |
#include <iostream>
#include <assert.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
class SeqStack //顺序栈类定义
{
private:
char *elements; //栈元素存放数组
int top; //栈顶指针
int maxSize; //栈最大容量
void overflowProcess(); //栈的溢出处理
public:
SeqStack(int sz =50); //构造函数
~SeqStack()
{
delete []elements; //析构函数
}
void Push(char &x); //进栈
int Pop(char& x); //出栈
int getTop(char& x); //取栈顶内容
int IsEmpty() const
{
return top == -1;
}
int IsFull() const
{
return top == maxSize-1;
}
int getSize() const
{
return top+1;
}
void MakeEmpty()
{
top=-1;
}
void output();
};
SeqStack:: SeqStack(int sz)
{
elements=new char[sz];
assert(elements!=NULL);
top=-1;
maxSize=sz;
}
void SeqStack::overflowProcess()
{
//私有函数:当栈满则执行扩充栈存储空间处理
char *newArray = new char [2*maxSize]; //创建更大的存储数组
for (int i = 0; i <= top; i++)
newArray[i] = elements[i];
maxSize += maxSize;
delete [ ]elements;
elements = newArray; //改变elements指针
};
void SeqStack::Push(char & x)
{
//若栈满,则溢出处理,将元素x插入该栈栈顶
if (IsFull())
overflowProcess( ); //栈满
elements[++top] = x; //栈顶指针先加1, 再进栈
};
int SeqStack::Pop(char & x)
{
//若栈不空,函数退出栈顶元素并将栈顶元素的值赋给x,
//返回1,否则返回0
if (IsEmpty())
return 0;
x = elements[top--] ; //先取元素,栈顶指针退1
return 1; //退栈成功
};
int SeqStack::getTop(char& x)
{
//若栈不空则x为该栈栈顶元素
if (IsEmpty())
return 0;
x = elements[top];
return 1;
};
void SeqStack::output( )
{
cout<<"元素个数为:"<<top+1<<endl;
for (int i=0; i<=top; i++)
cout <<i+1<<":"<<elements[i] <<endl;
};
//整数栈
class SeqStackInt //顺序栈类定义
{
private:
int *elements; //栈元素存放数组
int top; //栈顶指针
int maxSize; //栈最大容量
void overflowProcess(); //栈的溢出处理
public:
SeqStackInt(int sz =50); //构造函数
~SeqStackInt()
{
delete []elements; //析构函数
}
void Push(int &x); //进栈
int Pop(int& x); //出栈
int getTop(int& x); //取栈顶内容
int IsEmpty() const
{
return top == -1;
}
int IsFull() const
{
return top == maxSize-1;
}
int getSize() const
{
return top+1;
}
void MakeEmpty()
{
top=-1;
}
void output();
};
SeqStackInt:: SeqStackInt(int sz)
{
elements=new int[sz];
assert(elements!=NULL);
top=-1;
maxSize=sz;
}
void SeqStackInt::overflowProcess()
{
//私有函数:当栈满则执行扩充栈存储空间处理
int *newArray = new int [2*maxSize]; //创建更大的存储数组
for (int i = 0; i <= top; i++)
newArray[i] = elements[i];
maxSize += maxSize;
delete [ ]elements;
elements = newArray; //改变elements指针
};
void SeqStackInt::Push(int & x)
{
//若栈满,则溢出处理,将元素x插入该栈栈顶
if (IsFull())
overflowProcess( ); //栈满
elements[++top] = x; //栈顶指针先加1, 再进栈
};
int SeqStackInt::Pop(int & x)
{
//若栈不空,函数退出栈顶元素并将栈顶元素的值赋给x,
//返回1,否则返回0
if (IsEmpty())
return 0;
x = elements[top--] ; //先取元素,栈顶指针退1
return 1; //退栈成功
};
int SeqStackInt::getTop(int& x)
{
//若栈不空则x为该栈栈顶元素
if (IsEmpty())
return 0;
x = elements[top];
return 1;
};
void SeqStackInt::output( )
{
cout<<"元素个数为:"<<top+1<<endl;
for (int i=0; i<=top; i++)
cout <<i+1<<":"<<elements[i] <<endl;
};
//浮点数栈
class SeqStackDouble //顺序栈类定义
{
private:
double *elements; //栈元素存放数组
int top; //栈顶指针
int maxSize; //栈最大容量
void overflowProcess(); //栈的溢出处理
public:
SeqStackDouble(int sz =50); //构造函数
~SeqStackDouble()
{
delete []elements; //析构函数
}
void Push(double &x); //进栈
int Pop(double& x); //出栈
int getTop(double& x); //取栈顶内容
int IsEmpty() const
{
return top == -1;
}
int IsFull() const
{
return top == maxSize-1;
}
int getSize() const
{
return top+1;
}
void MakeEmpty()
{
top=-1;
}
void output();
};
SeqStackDouble:: SeqStackDouble(int sz)
{
elements=new double[sz];
assert(elements!=NULL);
top=-1;
maxSize=sz;
}
void SeqStackDouble::overflowProcess()
{
//私有函数:当栈满则执行扩充栈存储空间处理
double *newArray = new double [2*maxSize]; //创建更大的存储数组
for (int i = 0; i <= top; i++)
newArray[i] = elements[i];
maxSize += maxSize;
delete [ ]elements;
elements = newArray; //改变elements指针
};
void SeqStackDouble::Push(double & x)
{
//若栈满,则溢出处理,将元素x插入该栈栈顶
if (IsFull())
overflowProcess( ); //栈满
elements[++top] = x; //栈顶指针先加1, 再进栈
};
int SeqStackDouble::Pop(double & x)
{
//若栈不空,函数退出栈顶元素并将栈顶元素的值赋给x,
//返回1,否则返回0
if (IsEmpty())
return 0;
x = elements[top--] ; //先取元素,栈顶指针退1
return 1; //退栈成功
};
int SeqStackDouble::getTop(double& x)
{
//若栈不空则x为该栈栈顶元素
if (IsEmpty())
return 0;
x = elements[top];
return 1;
};
void SeqStackDouble::output( )
{
cout<<"元素个数为:"<<top+1<<endl;
for (int i=0; i<=top; i++)
cout <<i+1<<":"<<elements[i] <<endl;
};
int isp(char x)
{
switch(x)
{
case '#':return 0;case '(':return 1;case '*':return 5;
case '/':return 5;case '%':return 5;case '+':return 3;
case '-':return 3;case ')':return 6;
}
}
int icp(char x)
{
switch(x)
{
case '#':return 0;case '(':return 6;case '*':return 4;
case '/':return 4;case '%':return 4;case '+':return 2;
case '-':return 2;case ')':return 1;
}
}
//中缀转后缀
int transfer(char (&Infix)[100],char (&Postfix)[100][100],int &Inlast,int &polast)//Infix,postfix指针
{
SeqStack S;
int flag=0;//0表示整数,1表示浮点数
char ch='#',ch1,op;
S.Push(ch);
ch=Infix[Inlast++];
while(!S.IsEmpty()&&ch!='#')
{
if (isdigit(ch)||ch=='.')
{
if(ch=='.')
flag=1;
int len=strlen(Postfix[polast]);
Postfix[polast][len]=ch;
ch=Infix[Inlast++];
}
else
{
S.getTop(ch1);
if (isp(ch1)<icp(ch))
{
polast++;
S.Push(ch);
ch=Infix[Inlast++];
}
else if (isp(ch1)>icp(ch))
{
S.Pop(op);
polast++;
if(op!='#')
Postfix[polast][0]=op;
}
else
{
S.Pop(op);
if(op=='(')
ch=Infix[Inlast++];
}
}
}
return flag;
// //验证
// for(int k=0;k<polast;k++)
// printf("%s\n",Postfix[k]);
}
template<typename T>
T calculate(T leftnum,T rightnum,char x)
{
switch(x)
{
case '+':
return leftnum+rightnum;
case '-':
return leftnum-rightnum;
case '*':
return leftnum*rightnum;
case '/':
return leftnum/rightnum;
case '%':
return (int)leftnum%(int)rightnum;
}
}
//求整数解
int SolutionInt(char (&PoString)[100][100],int &Inlast,int &polast)
{
int sum=0,Result;
SeqStackInt SI;
for(int k=0;k<polast;k++)//循环后缀表达式数组并将它们入栈计算
{
int len=strlen(PoString[k]);
if(!len)
continue;
else if(isdigit(PoString[k][0]))
{
sum=atoi(PoString[k]);
SI.Push(sum);
sum=0;
}
else
{
int leftnum,rightnum;
SI.Pop(rightnum);
SI.Pop(leftnum);
Result=calculate(leftnum,rightnum,PoString[k][0]);
SI.Push(Result);
}
}
SI.getTop(Result);
return Result;
}
//求浮点数
double SolutionDouble(char (&PoString)[100][100],int &Inlast,int &polast)
{
double sum=0,Result;
SeqStackDouble SD;
for(int k=0;k<polast;k++)//循环后缀表达式数组并将它们入栈计算
{
int len=strlen(PoString[k]);
if(!len)
continue;
else if(isdigit(PoString[k][0]))
{
sum=atof(PoString[k]);
SD.Push(sum);
sum=0;
}
else
{
double leftnum,rightnum;
SD.Pop(rightnum);
SD.Pop(leftnum);
Result=calculate(leftnum,rightnum,PoString[k][0]);
SD.Push(Result);
}
}
SD.getTop(Result);
return Result;
}
//中缀表达式,其中若ff返回0,则表示整形,若ff返回1,则表示浮点型
double Process(char (&InString)[100],int &ff)
{
char PoString[100][100];//后缀表达式
int Inlast,polast,flag;
Inlast=0;
polast=0;
flag=transfer(InString,PoString,Inlast,polast);
if(!flag)
{
int Result=SolutionInt(PoString,Inlast,polast);
ff=0;
return Result;
}
else
{
double Result=SolutionDouble(PoString,Inlast,polast);
ff=1;
return Result;
}
}
int main()
{
char InString[100];//中缀表达式
scanf("%s",InString);
int a;
double b;
b=Process(InString,a);
//printf("%d\n",a);
if(a)
printf("%lf\n",b);
else
printf("%d\n",(int)b);
return 0;
}
运行结果
浮点数运算

整数运算

281

被折叠的 条评论
为什么被折叠?



