刚刚学习C语言的时候我们都写过计算器,但是当时写的计算器只能进行一步四则运算,对于一次输入类似这种(1+2)*3+4的运算则没有办法计算。
本篇博客利用栈这种数据结构实现了支持带括号的表达式求值计算器。
C语言实现表达式求值的完整代码
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
typedef int ElemType;
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
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(1);
}
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, (s->stacksize + STACKINCREMENT) * sizeof(ElemType));
if (!s->base){
exit(1);
}
s->top = s->base + s->stacksize;
s->stacksize += STACKINCREMENT;
}
*(s->top) = e;
s->top++;
}
void Pop(sqStack* s, char* e){
if (s->top == s->base)
exit(1);
*e = *(--(s->top));
}
char GetTop(sqStack* s){
if (s->top == s->base){
return -1;
}
return *(s->top - 1);
}
int In(char e){
if (e == '+' || e == '-' || e == '*' || e == '/' || e == '(' || e == ')' || e == '#')
return 1;//是
else
return 0; //不是
}
char Precede(char a, char b) {
char f;
if (a == '+' || a == '-'){
if (b == '+' || b == '-' || b == ')' || b == '#')
f = '>';
else if (b == '*' || b == '/' || b == '(')
f = '<';
}
else if (a == '*' || a == '/'){
if (b == '+' || b == '-' || b == '*' || b == '/' || b == ')' || b == '#')
f = '>';
else if (b == '(')
f = '<';
}
else if (a == '('){
if (b == '+' || b == '-' || b == '*' || b == '/' || b == '(')
f = '<';
else if (b == ')')
f = '=';
}
else if (a == ')'){
if (b == '+' || b == '-' || b == '*' || b == '/' || b == ')' || b == '#')
f = '>';
}
else if (a == '#'){
if (b == '+' || b == '-' || b == '*' || b == '/' || b == '(')
f = '<';
else if (b == '#')
f = '=';
}
return f;
}
char Operate(char a, char theta, char b){
char c;
a = a - '0';
b = b - '0';
if (theta == '+')
c = a + b + '0';
else if (theta == '-')
c = a - b + '0';
else if (theta == '*')
c = a * b + '0';
else if (theta == '/')
c = a / b + '0';
return c;
}
int EvaluateExpression(){
sqStack OPND, OPTR;
char ch, a, b, theta, x;
InitStack(&OPND);//寄存操作数和运算结果
InitStack(&OPTR);//寄存运算符
Push(&OPTR, '#');
ch = getchar();
while (ch != '#' || GetTop(&OPTR) != '#'){
if (!In(ch)){
Push(&OPND, ch);
ch = getchar();
}
else{
switch (Precede(GetTop(&OPTR), ch)){
case '<':
Push(&OPTR, ch);
ch = getchar();
break;
case '>':
Pop(&OPTR, &theta);
Pop(&OPND, &b);
Pop(&OPND, &a);
Push(&OPND, Operate(a, theta, b));
break;
case '=':
Pop(&OPTR, &x);
ch = getchar();
break;
}
}
}
return GetTop(&OPND) - '0';
}
int main(){
printf("请输入算术表达式,以#结束\n");
printf("例如\t 1*(2-1)# \t\n");
printf("结果是: %d\n", EvaluateExpression());
return 0;
}