基于逆波兰表达式的计算器
首先我们需要了解下一般表达式如何转化为逆波兰表达式。如下:
1+(20-3)*4+10/5 如何转化为逆波兰表达式 1 20 3 - 4 * + 10 5 / +
一般表达式转化为逆波兰表达式的步骤如下:
从左到右遍历一般表达式的每个数字和符号,若是数字则直接输出,若是符号,则判断其与栈顶符号的优先级,是右括号或者优先级低于栈顶符号,则栈顶元素依次出栈并输出,直到遇到左括号或栈空才将等待入栈的符号入栈。
代码如下
#include<time.h>
#include<math.h>
#include<ctype.h>
# include <stdio.h>
# include <stdlib.h>
#include<string.h>
#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10
#define MAXBUFFER 10
typedef char ElemType;
typedef struct
{
ElemType *base;//栈底指针
ElemType *top;//栈顶指针
int stacksize;//栈当前可使用的最大容量
}sqstack;
void InitStack(sqstack *s)
{
s->base = ( ElemType*)malloc(STACK_INIT_SIZE*sizeof( ElemType));
if(!(s->base))exit(0);
s->top = s->base;
s->stacksize = STACK_INIT_SIZE;
}
void Push(sqstack *s, ElemType e)
{
if(s->top - s->base >= s->stacksize)
{
s->base = ( ElemType*)realloc(s->base,(STACKINCREMENT + s->stacksize)*sizeof(ElemType));
if(!(s->base))exit(0);
s->top = s->base+ s->stacksize;
s->stacksize = s->stacksize + STACKINCREMENT;
}
*(s->top) = e;
(s->top)++;
}
void Pob(sqstack *s, ElemType *e)
{
if(s->top==s->base)return ;
s->top--;
*e = *(s->top);
}
int StackLen(sqstack s)
{
return (s.top - s.base);
}
typedef double ElemType1;
typedef struct
{
ElemType1 *base;//栈底指针
ElemType1 *top;//栈顶指针
int stacksize;//栈当前可使用的最大容量
}sqstack1;
void InitStack1(sqstack1 *s)
{
s->base = ( ElemType1*)malloc(STACK_INIT_SIZE*sizeof( ElemType1));
if(!(s->base))exit(0);
s->top = s->base;
s->stacksize = STACK_INIT_SIZE;
}
void Push1(sqstack1 *s, ElemType1 e)
{
if(s->top - s->base >= s->stacksize)
{
s->base = ( ElemType1*)realloc(s->base,(STACKINCREMENT + s->stacksize)*sizeof(ElemType1));
if(!(s->base))exit(0);
s->top = s->base+ s->stacksize;
s->stacksize = s->stacksize + STACKINCREMENT;
}
*(s->top) = e;
(s->top)++;
}
void Pob1(sqstack1 *s, ElemType1 *e)
{
if(s->top==s->base)return ;
s->top--;
*e = *(s->top);
}
int StackLen1(sqstack1 s)
{
return (s.top - s.base);
}
void midConverToLast(char * &str,int n)
{
str = (char*)malloc(n*sizeof(char));
sqstack s;
char c,e;
InitStack(&s);
printf("请输入中缀表达式,以#作为结束标志:");
scanf("%c",&c);
int i = 0;
while('#'!=c)
{
while(c >= '0' && c <= '9')
{
//printf("%c",c);
str[i++] = c;
scanf("%c",&c);
if(c < '0' || c > '9')
{
//printf(" ");
str[i++] = ' ';
}
}
if(c == ')')
{
Pob(&s,&e);
while(e != '(')
{
//printf("%c ",e);
str[i++] = e;
str[i++] = ' ';
Pob(&s,&e);
}
}
else if(c =='+'||c=='-')
{
if(!StackLen(s))
{
Push(&s,c);
}
else
{
do
{
Pob(&s,&e);
if('('==e)
{
Push(&s,e);
}
else
{
//printf("%c ",e);
str[i++] = e;
str[i++] = ' ';
}
}while(StackLen(s) && e!='(');
Push(&s,c);
}
}
else if(c=='*'||c=='/'||'('==c)
{
Push(&s,c);
}
else if(c=='#')
{
break;
}
else
{
printf("%n出错:输入格式错误\n ");
}
scanf("%c",&c);
}
while(StackLen(s))
{
Pob(&s,&e);
str[i++] = e;
str[i++] = ' ';
}
str[i]='\0';
}
int main()
{
sqstack1 s;
char c;
int i = 0;
double d,e;
InitStack1(&s);
char str[MAXBUFFER];
char *point = NULL;
int n = 30;
midConverToLast(point,n);
int j = 0;
while((c = point[j])!='\0')
{
while(isdigit(c) || c=='.')
{
str[i++] = c;
str[i] ='\0';
if(i>=10)
{
printf("输入的单个数据位数过长\n");
return -1;
}
c = point[++j];
if(c==' ')
{
d = atof(str);
Push1(&s,d);
i = 0;
break;
}
}
switch(c)
{
case '+':
Pob1(&s,&e);
Pob1(&s,&d);
Push1(&s,d + e);
printf("加法的结果为%f\n",d + e);
break;
case '-':
Pob1(&s,&e);
Pob1(&s,&d);
Push1(&s,d - e);
printf("减法的结果为%f\n",d - e);
break;
case '*':
Pob1(&s,&e);
Pob1(&s,&d);
Push1(&s,d * e);
printf("乘法的结果为%f\n",d * e);
break;
case '/':
Pob1(&s,&e);
Pob1(&s,&d);
if(e!= 0)
{
Push1(&s,d/e);
}
else
{
printf("出错,除数为0\n");
return -1;
}
printf("除法的结果为%f\n",d/e);
break;
}
c = point[++j];
}
Pob1(&s,&d);
printf("最后的运行结果为%f\n",d);
return 0;}