/*brief function:
* 用纯C实现的简单表达式求值
* 输入要求:表达式应正确,各字符间无空格,以等号结束,如可这样输入:1+2*(50/(1+2*(1+7)))-3=
* 只支持简单的加减乘除算法
*/
#include
#include
#include
typedef struct{
char *top;
char *base;
int stacksize;
}Optr_Stack;
typedef struct{
float *top;
float *base;
int stacksize;
}Opnd_Stack;
typedef unsigned char Status;
#define OK 1
#define FALSE 0
#define OVERFLOW -1
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
Status InitOptrStack(Optr_Stack *s)
{
s->base = (char *)malloc(sizeof(char) * STACK_INIT_SIZE);
if(s->base == NULL)
exit(OVERFLOW);
s->top = s->base;
s->stacksize = STACK_INIT_SIZE;
return OK;
}
Status InitOpndStack(Opnd_Stack *s)
{
s->base = (float *)malloc(sizeof(float) * STACK_INIT_SIZE);
if(s->base == NULL)
exit(OVERFLOW);
s->top = s->base;
s->stacksize = STACK_INIT_SIZE;
return OK;
}
Status DestroyOptrStack(Optr_Stack *s)
{
free(s->top);
free(s->base);
return OK;
}
Status DestroyOpndStack(Opnd_Stack *s)
{
free(s->top);
free(s->base);
return OK;
}
Status OpndStackEmpty(Opnd_Stack *s)
{
if(s->top == s->base)
return FALSE;
return OK;
}
Status OptrStackEmpty(Optr_Stack *s)
{
if(s->top == s->base)
return FALSE;
return OK;
}
Status GetOpndTop(Opnd_Stack *s, float *n)
{
if(s->top == s->base)
return FALSE;
*n = *(s->top - 1);
return OK;
}
Status GetOptrTop(Optr_Stack *s, char *e)
{
if(s->top == s->base)
return FALSE;
*e = *(s->top - 1);
return OK;
}
Status OpndPush(Opnd_Stack *s, float n)
{
if(s->top - s->base >= s->stacksize)
{
s->base = (float *)realloc(s->base, (s->stacksize + STACKINCREMENT)*sizeof(float));
if(!s->base)
exit(OVERFLOW);
s->top = s->base + s->stacksize;
s->stacksize += STACKINCREMENT;
}
*s->top = n;
s->top++;
return OK;
}
Status OptrPush(Optr_Stack *s, char c)
{
if(s->top - s->base >= s->stacksize)
{
s->base = (char *)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(char));
if(!s->base)
exit(OVERFLOW);
s->top = s->base + s->stacksize;
s->stacksize = s->stacksize + STACKINCREMENT;
}
*s->top = c;
s->top++;
return OK;
}
Status OpndPop(Opnd_Stack *s, float *n)
{
if(s->top == s->base)
return FALSE;
s->top--;
*n = *s->top;
return OK;
}
Status OptrPop(Optr_Stack *s, char *e)
{
if(s->top == s->base)
return FALSE;
s->top--;
*e = *s->top;
return OK;
}
/*!
*检测输入的字符是运算符还是数字
*/
Status Chk_ch(char ch)
{
if(((ch >= '0') && (ch <= '9')) || (ch == '.'))
return FALSE;
return OK;
}
char Precede(char ch1, char ch2)
{
char ret_val;
if((ch1 == '+') || (ch1 == '-'))
{
if((ch2 == '+') || (ch2 == '-') || (ch2 == '=') || (ch2 == ')'))
ret_val = '>';
else if((ch2 == '*') || (ch2 == '/') || (ch2 == '('))
ret_val = '<';
}
else if((ch1 == '*') || (ch1 == '/'))
{
if(ch2 == '(')
ret_val = '<';
else
ret_val = '>';
}
else if(ch1 == '(')
{
if(ch2 == ')')
ret_val = '=';
else
ret_val = '<';
}
else if(ch1 == '=')
{
ret_val = '<';
}
return ret_val;
}
float Operate(float a, char theta, float b)
{
switch(theta)
{
case '+':
return (a + b);
case '-':
return (a - b);
case '*':
return (a*b);
case '/':
return (a/b);
}
return a+b;
}
int main(void)
{
Optr_Stack stk_optr;
Opnd_Stack stk_opnd;
char ch, ch_optr, x;
char opnd[20];
unsigned char i;
char theta;
float a, b, result;
InitOptrStack(&stk_optr);
InitOpndStack(&stk_opnd);
OptrPush(&stk_optr, '=');
i = 0;
memset(opnd, '\0', sizeof(opnd));
ch = getchar();
if(ch == '-')
{//输入的第一个数字为负数
opnd[i++] = ch;
ch = getchar();
}
GetOptrTop(&stk_optr, &ch_optr);
while((ch != '=') || (ch_optr != '='))
{
if(Chk_ch(ch) == FALSE)
{
opnd[i++] = ch;
ch = getchar();
}
else
{
if(i > 0)
{//将输入的所有字符转换为数字,压入操作数栈
OpndPush(&stk_opnd, atof(opnd));
i = 0;
memset(opnd, '\0', sizeof(opnd));
}
GetOptrTop(&stk_optr, &ch_optr);
switch(Precede(ch_optr, ch))
{
case '<':
OptrPush(&stk_optr, ch);
ch = getchar();
break;
case '=':
OptrPop(&stk_optr, &x);
ch = getchar();
break;
case '>':
OptrPop(&stk_optr, &theta);
OpndPop(&stk_opnd, &b);
OpndPop(&stk_opnd, &a);
OpndPush(&stk_opnd, Operate(a, theta, b));
break;
default:
break;
}
}
GetOptrTop(&stk_optr, &ch_optr);
}
GetOpndTop(&stk_opnd, &result);
printf("%f", result);
DestroyOpndStack(&stk_opnd);
DestroyOptrStack(&stk_optr);
}
阅读(1039) | 评论(0) | 转发(0) |