c语言版的
#include<iostream>
#include<stdio.h>
#define MAXSIZE 100
using namespace std;
struct SqStack{
double *base;
double *top;
double SatckSize;
}s_val;
struct SqStack_ter{
double *base;
double *top;
double SatckSize;
}s_ter;
template <class T>
void InitStack(T &S)
{
S.base=new double[MAXSIZE];
if(!S.base) cout<<"error"<<endl;
S.top=S.base;
S.SatckSize=MAXSIZE;
}
double GetTop_val(struct SqStack &s)
{
if(s.top!=s.base)
return *(s.top-1);
}
char GetTop_ter(struct SqStack_ter &s)
{
if(s.top!=s.base)
return *(s.top-1);
}
void Push_val(struct SqStack &s,double e)
{
if(s.top-s.base==s.SatckSize) cout<<"error"<<endl;
*s.top++=e;
}
void Pop_val(struct SqStack &s,double &e)
{
if(s.top==s.base) cout<<"error"<<endl;
e=*--s.top;
}
void Push_ter(struct SqStack_ter &s,char &e)
{
if(s.top-s.base==s.SatckSize) cout<<"error"<<endl;
*s.top++=e;
}
void Pop_ter(struct SqStack_ter &s,char &e)
{
if(s.top==s.base) cout<<"error"<<endl;
e=*--s.top;
}
double calculate(double b, char theta, double a) //计算b theta a
{
switch (theta)
{
case '+':
return (double)b + a;
case '-':
return (double)b - a;
case '*':
return (double)b * a;
case '/':
return (double)b / a;
default:
break;
}
}
int getIndex(char theta) //获取theta所对应的索引
{
char B[7]={'+','-','*','/','(',')','#'};
int i=0;
while(theta !=B[i]) {i++;}
return i;
}
char getPriority(char theta1, char theta2) //获取theta1与theta2之间的优先级
{
const char priority[][7] = //运算符间的优先级关系
{
{ '>','>','<','<','<','>','>' },
{ '>','>','<','<','<','>','>' },
{ '>','>','>','>','<','>','>' },
{ '>','>','>','>','<','>','>' },
{ '<','<','<','<','<','=','0' },
{ '>','>','>','>','0','>','>' },
{ '<','<','<','<','<','0','=' },
};
int index1 = getIndex(theta1);
int index2 = getIndex(theta2);
return priority[index1][index2];
}
double getAnswer(){
InitStack(s_val);
InitStack(s_ter);
char tep='#';
Push_ter(s_ter,tep);
bool isNum=false;
double result=0;
// char *p=new char[100];
// cin>>p;这是另一种存储方法,先把表达式存放在数组里,然后再依次求解
int i=0;
char c=getchar();
while(c!='#')
{
if(isdigit(c))
{
if(isNum)
{
//如果之前的数是数字,就要进位
double a;
Pop_val(s_val,a);
Push_val(s_val,double(a*10+(c-'0')));
}
else
{
//如果之前不是数字,直接push
Push_val(s_val,double((c-'0')));
isNum=true;
}
//i++;
c = getchar();
}
else
{
isNum=false;
char a;
//Pop_ter(s_ter,a);
a=GetTop_ter(s_ter);
switch(getPriority(a,c))//获取栈顶元素与当前操作符的优先级
{
case '>':
char theta;
Pop_ter(s_ter,theta); //运算符出
double a_num;
Pop_val(s_val,a_num); //操作数出栈
double b_num;
Pop_val(s_val,b_num); //操作数出栈
Push_val(s_val,(calculate(b_num, theta, a_num)));
// c = getchar(); 当读到需要计算的符号时,运算符出栈,两个操作数出栈,然后计算后将结果push栈中。
//这里为何不再继续读char,不太明白
break;
case '<':
Push_ter(s_ter,c);
c = getchar();
break;
case '=':
char temp;
Pop_ter(s_ter,temp);
c = getchar();
break;
}
}
}
return calculate(*(s_val.top-2),GetTop_ter(s_ter),GetTop_val(s_val));
//按此思路计算,堆栈中的top-1与top-2存放着最后两个未处理的数
//需要做次计算才能得到最终的结果,具体原因是因为 当c读到#时,s_val中仍存放着两个未处理的数字
//而s_ter中仍存放着最后一个操作符。
}
int main(){
double ans = getAnswer();
cout <<"答案"<<ans<< endl;
return 0;
}
运行
实验报告中要求计算小数,暂时没有想法,然后还想用类来写另一个版本的堆栈