/*暂时没有加入小数的分析,表达式中只能用整数*/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR 0
#define OK 1
#define NUM 3
#define FLAG 4
#define BIG 1
#define EQUAL 0
#define SMALL -1
#define UNKNOWN 2
typedef struct
{
char formula[500];
char flagStack[300];
int flagStackTop;
float numStack[300];
int numStackTop;
}Eva;
/************函数声明**********************/
void initStack(Eva *); //初始化堆栈
void getExpression(Eva *); //输入算术表达式
int checkFormula(Eva *); //检查表达式的合法性
float EvaExpress(Eva *); //计算算术表达式,返回计算结果
int getNumOrFlag(Eva *,int,char *,int *); //从输入字符串中取得数字或运算符,并返回下次取值的位置
int flagComp(char,char); //比较两个运算符的优先级,大于返回1,等于返回0,小于返回-1
/****************函数定义*********************/
void initStack(Eva *fml)
{
int i;
for(i=0;i<300;i++)
{
fml->formula[i]='\0';
fml->flagStack[i]='\0';
fml->numStack[i]='\0';
}
for(i=300;i<500;i++) fml->formula[i]='\0';
fml->flagStack[0]='#';
fml->flagStackTop=1;
fml->numStackTop=0;
}//end initStack
void getExpression(Eva *fml)
{
printf("Please input a formula(Not more than 450 characters):");
gets(fml->formula);
return;
}//end getExpression
int checkFormula(Eva *fml)
{
char *p;
int bracketDou=0;
p=fml->formula;
if(!(*p))
{
printf("No formula input!\n");
return ERROR;
}
if(*p==')' || *p=='+' || *p=='-' || *p=='*' || *p=='/') return ERROR;
while(*p)
{
if(*p=='(')
{
bracketDou++;
if(*(p+1)=='+' || *(p+1)=='-' || *(p+1)=='*' || *(p+1)=='/' || *(p+1)==')') return ERROR;
}
if(*p==')')
{
bracketDou--;
if(*(p+1)!='+' && *(p+1)!='-' && *(p+1)!='*' && *(p+1)!='/' && *(p+1)!=')' && *(p+1)!='\0') return ERROR;
if(*(p-1)=='+' || *(p-1)=='-' || *(p-1)=='*') return ERROR;
if(*(p-1)=='/') return ERROR;
}
if(bracketDou<0) return ERROR;
if(*p!='+' && *p!='-' && *p!='*' && *p!='/' && *p!=')' && *p!='(')
if(*p<'0' || *p>'9') return ERROR;
if(*p=='/' && *(p+1)=='0')
{
printf("A number is devided by zero!\n");
return ERROR;
}
p++;
}
if(bracketDou!=0) return ERROR;
if(*(p-1)=='+' || *(p-1)=='-' || *(p-1)=='*' || *(p-1)=='/' || *(p-1)=='(') return ERROR;
strcat(fml->formula,"#");
return OK;
}//end checkFormula
int getNumOrFlag(Eva *fml,int pos,char *strNumOrFlag,int *NumOrFlag)
{
int i=pos;
int j=0;
char *str=fml->formula;
if(*(str+i)=='#')
{
*NumOrFlag=FLAG;
strNumOrFlag[0]='#';
strNumOrFlag[1]='\0';
return 0;
}
if(*(str+i)<'0' || *(str+i)>'9')
{
*NumOrFlag=FLAG;
strNumOrFlag[0]=*(str+i);
strNumOrFlag[1]='\0';
return i+1;
}
else
{
*NumOrFlag=NUM;
while(*(str+i)!='\0' && *(str+i)>='0' && *(str+i)<='9')
{
strNumOrFlag[j++]=*(str+i);
strNumOrFlag[j]='\0';
i++;
}
}
return i;
}//end getNumOrFlag
int flagComp(char flag1,char flag2)
{
if(flag1=='+' || flag1=='-')
{
if(flag2=='+' || flag2=='-') return BIG;
if(flag2==')') return BIG;
if(flag2=='#') return BIG;
else return SMALL;
}
if(flag1=='*' || flag1=='/')
{
if(flag2=='(') return SMALL;
else return BIG;
}
if(flag1=='(')
{
if(flag2==')') return EQUAL;
else if(flag2=='#') return UNKNOWN;
else return SMALL;
}
if(flag1==')')
{
if(flag2==')') return UNKNOWN;
else return BIG;
}
if(flag1=='#')
{
if(flag2=='#') return EQUAL;
if(flag2==')') return UNKNOWN;
else return SMALL;
}
}//end flagComp
float EvaExpress(Eva *fml)
{
char strNumOrFlag[200];
float result;
int getPos=0;
float midNum;
float num1,num2;
char flag;
int NumOrFlag;
getPos=getNumOrFlag(fml,getPos,strNumOrFlag,&NumOrFlag);
while(*strNumOrFlag!='#' || (fml->flagStack)[fml->flagStackTop-1]!='#')
{
if(NumOrFlag==NUM)
{
midNum=atof(strNumOrFlag);
(fml->numStack)[fml->numStackTop]=midNum;
fml->numStackTop++;
getPos=getNumOrFlag(fml,getPos,strNumOrFlag,&NumOrFlag);
}
else
{
switch(flagComp(fml->flagStack[fml->flagStackTop-1],*strNumOrFlag))
{
case SMALL:
fml->flagStack[fml->flagStackTop]=*strNumOrFlag;
fml->flagStackTop++;
getPos=getNumOrFlag(fml,getPos,strNumOrFlag,&NumOrFlag);
break;
case EQUAL:
fml->flagStackTop--;
getPos=getNumOrFlag(fml,getPos,strNumOrFlag,&NumOrFlag);
break;
case BIG:
flag=fml->flagStack[fml->flagStackTop-1];
fml->flagStackTop--;
num2=fml->numStack[fml->numStackTop-1];
fml->numStackTop--;
num1=fml->numStack[fml->numStackTop-1];
fml->numStackTop--;
switch(flag)
{
case '+':
result=num1+num2;
break;
case '-':
result=num1-num2;
break;
case '*':
result=num1*num2;
break;
case '/':
result=num1/num2;
break;
default:
printf("Calculate error... Press any key to exit!\n");
getch();
exit(1);
break;
}
fml->numStack[fml->numStackTop]=result;
fml->numStackTop++;
break;
default:
printf("Unknown error! Press any key to exit!...\n");
getch();
exit(1);
break;
}
}
}
result=fml->numStack[(fml->numStackTop)-1];
return result;
}//end EvaExpress
/***********************主函数部分*******/
int main(void)
{
Eva Evaluate;
int flag;
float result;
initStack(&Evaluate);
getExpression(&Evaluate);
flag=checkFormula(&Evaluate);
if(flag==ERROR)
{
printf("The expression you input is invalid! Press any key to exit...\n");
getch();
exit(1);
}
printf("%f\n",EvaExpress(&Evaluate));
getch();
return 0;
}
[此贴子已经被作者于2007-9-29 22:51:27编辑过]
偶学编程,也许本身就是一个错。。。