如从键盘上输入
2+3*3/(5-2)
然后输出
5
3q
原创]表达式计算器
*/ --------------------------------------------------------------------------------------
*/ 出自: 编程中国 http://www.bc-cn.net
*/ 作者: josen0205 QQ:7007873
*/ 时间: 2007-9-22 编程论坛首发
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------
为了方便了解流程,在程序中把计算过程也输出了.而且栈操作的实现部分也是自己实现的.
程序用两个栈,optr寄存运算符,opnd寄存操作数和运算结果.输入的表达式以等号结束,例如:2*(1+2)=
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <malloc.h>
#define STACK_SIZE 100
#define APPEND_SIZE 10
struct SNode{
float data; /*存放操作数或者计算结果*/
char ch; /*存放运算符*/
};
struct Stack{
SNode *top;
SNode *base;
int size;
};
/*栈操作函数*/
int InitStack(Stack &S); /*创建栈*/
int DestroyStack(Stack &S); /*销毁栈*/
int ClearStack(Stack &S); /*清空栈*/
int GetTop(Stack S, SNode &e); /*取出栈顶结点并返回节点值*/
int Push(Stack &S,SNode e); /*将结点e压入栈*/
int Pop(Stack &S,SNode &e); /*删除栈顶结点并返回其节点值*/
/*表达式计算器相关函数*/
char get_precede(char s,char c); /*判断运算符s和c的优先级*/
int isOpr(char c); /*判断输入的字符是不是运算符,是则返回0,否返回1*/
float operate(float x, char opr, float y); /*计算x和y经过运算符opr计算后的结果*/
float compute(); /*表达式结算器主函数*/
int InitStack(Stack &S)
{
S.base=(SNode *)malloc(STACK_SIZE * sizeof(struct SNode));
if(S.base==NULL)
{
printf("动态分配内存失败!");
return -1;
}
S.top=S.base;
S.size=STACK_SIZE;
return 0;
}
int DestroyStack(Stack &S)
{
free(S.base);
return 0;
}
int ClearStack(Stack &S)
{
S.top=S.base;
return 0;
}
int GetTop(Stack S,SNode &e)
{
if(S.top==S.base)
{
printf("栈以为空!");
return -1;
}
e=*(S.top-1);
return 0;
}
int Push(Stack &S,SNode e)
{
if(S.top-S.base>=S.size)
{
S.base=(SNode *)realloc(S.base,(S.size+APPEND_SIZE)*sizeof(struct SNode));
if(S.base==NULL)
{
printf("动态分配内存失败!");
return -1;
}
S.top=S.base+S.size;
S.size+=APPEND_SIZE;
}
*S.top=e;
S.top++;
return 0;
}
int Pop(Stack &S,SNode &e)
{
if(S.top==S.base)
{
printf("栈为空!");
return -1;
}
e=*(S.top-1);
S.top--;
return 0;
}
char get_precede(char s,char c)
{
switch(s)
{
case '+':
case '-':
if(c=='+'||c=='-')
return '>';
else if(c=='*'||c=='/')
return '<';
else if(c=='(')
return '<';
else if(c==')')
return '>';
else
return '>';
case '*':
case '/':
if(c=='+'||c=='-')
return '>';
else if(c=='*'||c=='/')
return '>';
else if(c=='(')
return '<';
else if(c==')')
return '>';
else
return '>';
case '(':
if(c=='+'||c=='-')
return '<';
else if(c=='*'||c=='/')
return '<';
else if(c=='(')
return '<';
else if(c==')')
return '=';
else
return 'E';
case ')':
if(c=='+'||c=='-')
return '>';
else if(c=='*'||c=='/')
return '>';
else if(c=='(')
return 'E';
else if(c==')')
return '>';
else
return '>';
case '#':
if(c=='+'||c=='-')
return '<';
else if(c=='*'||c=='/')
return '<';
else if(c=='(')
return '<';
else if(c==')')
return 'E';
else
return '=';
default:
break;
}
return 0;
}
int isOpr(char c)
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'||c=='=')
return 0;
else
return 1;
}
float operate(float x, char opr, float y)
{
float result;
switch (opr)
{
case '+':
result = x + y;
break;
case '-':
result = x - y;
break;
case '*':
result = x * y;
break;
case '/':
if (y == 0)
{
printf("Divided by zero!\n");
return 0;
}
else
{
result = x / y;
break;
}
default:
printf("Bad Input.\n");
return 0;
}
return result;
}
float compute() /*计算的时候运算符栈顶结点的优先级始终最低*/
{
Stack optr,opnd;
struct SNode opr_in,opn_in,opr_top,opn_tmp,e,a,b,opr_t;
char c;
char buf[16];
int i=0;
InitStack(optr); /*用于寄存运算符*/
InitStack(opnd); /*用于寄存操作数和计算结果*/
memset(buf,0,sizeof(buf));
printf("Enter your expression:");
opr_in.ch='#';
Push(optr,opr_in); /*'#'入栈*/
GetTop(optr,opr_top);
c=getchar();
while(c!='='||opr_top.ch!='#')
{
if(isOpr(c)!=0) /*不是运算符则保存到buf中,以便得到操作数*/
{
buf[i]=c;
i++;
c=getchar();
}
else /*是运算符*/
{
buf[i]='\0';
if(i) /*判断buf是否为空,不为空则取出值,压入操作数寄存器,并将buf置为空*/
{
opn_in.data=(float)atof(buf);
Push(opnd,opn_in);
printf("opnd入栈:[%f]\n",opn_in.data);
i=0;
memset(buf,0,sizeof(buf));
}
opr_in.ch=c;
switch(get_precede(opr_top.ch,c)) /*根据运算符优先级做相应操作*/
{
case '<': /*优先级小于栈顶结点,则运算符入栈*/
Push(optr,opr_in);
printf("optr入栈:[%c]\n",opr_in.ch);
c=getchar();
break;
case '=': /*优先级等于栈顶结点,即是括号,去掉括号*/
Pop(optr,e);
printf("optr出栈:去掉括号\n");
c=getchar();
break;
case '>': /*优先级大于栈顶结点,取操作数和运算符计算*/
Pop(optr,opr_t);
printf("optr出栈:[%c]\n",opr_t.ch);
if(Pop(opnd,b)<0)
{
printf("Bad Input!\n");
fflush(stdin);
return -1;
}
printf("opnd出栈:[%f]\n",b.data);
if(Pop(opnd,a)<0)
{
printf("Bad Input!\n");
fflush(stdin);
return -1;
}
printf("opnd出栈:[%f]\n",a.data);
opn_tmp.data=operate(a.data,opr_t.ch,b.data); /*计算*/
Push(opnd,opn_tmp); /*将计算结果压入操作数寄存器*/
printf("结果入栈:[%f]\n",opn_tmp.data);
break;
}
}
GetTop(optr,opr_top); /*取出运算符寄存器栈顶结点*/
}
GetTop(opnd,opn_tmp);
DestroyStack(optr);
DestroyStack(opnd);
return opn_tmp.data;
}
int main()
{
char ch;
while(1)
{
printf("\nThe result is:%f\n",compute());
printf("Do you want to continue(y/n)?:") ;
ch=getch();
putchar(ch);
if(ch=='n'||ch=='N')
break;
else
system("cls");
}
getch();
return 0;
}
[此贴子已经被作者于2007-9-22 17:33:25编辑过]
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
typedef struct{
char data[MAXSIZE];
int top;
}SeqStack,*PSeqStack;
PSeqStack Init_SeqStack();
void Destroy_SeqStack(PSeqStack *S);
int Empty_SeqStack(PSeqStack S);
int Push_SeqStack(PSeqStack S,char x);
int Pop_SeqStack(PSeqStack S,char *x);
int GetTop_SeqStack(PSeqStack S,char *x);
int IsNum(char c);
char procede(char theta1,char theta2);
int infx_exp_value(char *infixexp,char *postfixexp);
double postfix_exp(char *A);
int main()
{
char *p,*q,str[30],str1[30];
double res;
gets(str);
p=str;
q=str1;
infx_exp_value(p,q);
res=postfix_exp(q);
printf("\nThe result is:%d\n",res);
return 0;
}
PSeqStack Init_SeqStack()
{
PSeqStack S=(PSeqStack)malloc(sizeof(SeqStack));
if(S) S->top=-1;
return S;
}
void Destroy_SeqStack(PSeqStack *S)
{
if(*S) free(*S);
*S=NULL;
return;
}
int Empty_SeqStack(PSeqStack S)
{
if(S->top==-1) return 1;
else return 0;
}
int Push_SeqStack(PSeqStack S,char x)
{
if(S->top==MAXSIZE) return 0;
else
{
S->top++;
S->data[S->top]=x;
return 1;
}
}
int Pop_SeqStack(PSeqStack S,char *x)
{
if(Empty_SeqStack(S)) return 0;
else
{
*x=S->data[S->top];
S->top--;
return 1;
}
}
int GetTop_SeqStack(PSeqStack S,char *x)
{
if(Empty_SeqStack(S)) return 0;
else
{
*x=S->data[S->top];
return 1;
}
}
int IsNum(char c)
{
if(c>='0'&&c<='9') return 1;
else return 0;
}
char procede(char theta1,char theta2)
{
int i,row,col;
static char CH[7]={'+','-','*','/','(',')','#'},
R[7][7]={
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','/'},
{'>','>','>','>','/','>','>'},
{'<','<','<','<','<','/','='}};
for(i=0;i<7;i++)
if(CH[i]==theta1)
{
row=i;break;
}
for(i=0;i<7;i++)
if(CH[i]==theta2)
{
col=i;break;
}
if(row<7&&col<7)
return (R[row][col]);
else
return ('/');
}
/////////////////////////////////////////////////////////////////////////////////////////
//问题主要在这个函数中
//问题太多,读你的程序已经杀死我不少脑细胞,只是找出我认为有问题的,可能还有问题没有发现
/////////////////////////////////////////////////////////////////////////////////////////
int infx_exp_value(char *infixexp,char *postfixexp)
{
PSeqStack S;
char w,topelement;
S=Init_SeqStack();
if(!S)
{
printf("init error!");
return 0;
}
Push_SeqStack(S,'#');
w=*infixexp;
while(!Empty_SeqStack(S))
{
if(IsNum(w))
{
*postfixexp=w;
postfixexp++;
// 加入 w=*(++infixexp); 更新w的值
}
else
{
GetTop_SeqStack(S,&topelement);
switch(procede(topelement,w))
{
//我认为应该定义'#'优先级最高 ,但是不把 '#'写入 *postfixexp,用if判断
case '>': //我认为应该定义'\0'优先级最低
Pop_SeqStack(S,&topelement);
*postfixexp=topelement;
postfixexp++;
//加入 Push_SeqStack(S,w);
//加入 if('\0'==w)return 0;
break;
case '=':
Pop_SeqStack(S,&topelement);
w=*(++infixexp);
break;
case '<':
Push_SeqStack(S,w);
w=*(++infixexp);
break;
defalut:printf("infixexp error!");
return 0;
}
}
}
*postfixexp='#';
Destroy_SeqStack(&S);
}
////////////////////////////////////////////////////////////
//这个函数也需要检查下,上面的把我搞晕了,下面没有看
////////////////////////////////////////////////////////////
double postfix_exp(char *A)
{
PSeqStack S;
char result,a,b,c;
char ch;
ch=*A++;
S=Init_SeqStack();
while(ch!='#')
{
if(IsNum(ch))
Push_SeqStack(S,ch-'0');
else
{
Pop_SeqStack(S,&b);
Pop_SeqStack(S,&a);
switch(ch)
{
case '+':
c=a+b;break;
case '-':
c=a-b;break;
case '*':
c=a*b;break;
case '/':
c=a/b;break;
}
Push_SeqStack(S,c);
}
ch=*A++;
}
GetTop_SeqStack(S,&result);
Destroy_SeqStack(&S);
return result;
}