Chinaunix首页 | 论坛 | 博客
  • 博客访问: 31368
  • 博文数量: 16
  • 博客积分: 205
  • 博客等级: 入伍新兵
  • 技术积分: 150
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-21 11:51
文章分类
文章存档

2014年(6)

2013年(3)

2012年(7)

我的朋友

分类: C/C++

2014-05-15 00:18:32

/*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) |
给主人留下些什么吧!~~