一个表达式由数字和运算符组成,建立两个栈,一个栈用来存数,另一个栈用来存运算符,再利用栈的基本操作来实现表达式的计算
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR -1
#define MAX_SIZE 30
typedef int ElemType;
typedef int Status;
栈的结构体
typedef struct
{
int top;
int bottom;
ElemType array[MAX_SIZE];
}SqStack;
字符串的结构体
typedef struct String
{
char ch[MAX_SIZE];
int length;
}String;
出始化栈
Status Init_Stack(SqStack *S)
{
S->top = S->bottom =0;
return OK;
}
压入栈
Status Push(SqStack *S, int e)
{
if(S->top == MAX_SIZE - 1)
{
return ERROR;
}
else
{
S->array[S->top] = e;
S->top++;
}
return OK;
}
弹出栈
int Pop(SqStack *S)
{
int e;
if(S->top == S->bottom)
{
return ERROR;
}
else
{
e = S->array[S->top - 1];
S->top--;
return e;
}
}
创建一个字符串类型的表达式
Status StrCreate(String *S)
{
int i = 0;
int len = 0;
printf("温馨提示:输入括号必须是英文状态,每个字符之间不要出现空格, 否则就会读取或计算出错呦!\n");
printf("Please enter a expression:\n");
gets(S->ch);
while(S->ch[i] != '\0')
{
len++;
i++;
}
S->length = len;
return OK;
}
判断字符是否为运算符
Status isOperator(char c)
{
int a;
switch(c)
{//是运算符返回1 是数字返回0 是空格返回-1
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':
a = 1;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
a = 0;
break;
case ' ':
a = -1;
break;
}
return a;
}
判断运算符的优先级
Status PRI(char oper1,char oper2)
{
//如果oper1>oper2返回1 如果oper1<oper2返回-1 如果oper1,,oper2是左右括号返回0
int pri = 0;
switch(oper1)
{
case '+':
case '-':
if(oper2 == '+' || oper2 == '-')
pri = 1; //oper1>oper2
else
pri = -1;
break;
case '*':
case '/':
if(oper2 == '*' || oper2 == '/' || oper2 == '+' || oper2 == '-' || oper2 == ')')
pri = 1;
else
pri = -1;
break;
case '(':
if(oper2==')') //右括号右侧不能马上出现左括号
{
printf("语法错误\n");
exit(0);
}
else
pri=-1; //oper1<oper2
break;
case ')':
if(oper1=='(')
pri=0;
else
pri=1;
break;
break;
}
return pri;
}
读取字符串中的数字
//若是多位数(例如:125,是字符1、字符2和字符5),要把字符串转化成数字
int Dushu(int n[], int j)//n[]是存放数字字符的数组 是数字字符的个数
{
int c;
int k;//c、k是循环变量
int l;
int e = 0;//转化之后的数字
l = j;
for(c = 0; c <= j; c++)
{
for(k = l - c; k > 0; k--)
{
n[c] = n[c]*10;
}
}
for(k = 0; k <= j; k++)
{
e = e + n[k];
}
return e;
}
两个数的计算结果
int Calc(int a,int oper,int b)
{
int e;//计算的结果
switch(oper) //根据运算符计算
{
case '+':
e = a+b;
break;
case '-':
e = a-b;
break;
case '*':
e = a*b;
break;
case '/':
if(b!=0)
e = a/b;
else
{
printf("除数不能为0!\n");
exit(0);
}
break;
}
return e;
}
解析字符串表达式
Status ParseExpression(SqStack *S1, SqStack *S2, String *S)
{ //S1是存放数字的栈 S2是存放运算符的栈
int i = 0;//循环变量 遍历字符串
int j = 0;//多位数的位数
int a = 0;
int b = 0;//a是运算符标记位,b数字标记位,用来判断表示的规范(例如:若表达式只有数字或只有运算符)
int n[MAX_SIZE];//存放多位数的 字符数字
int flag = 0;
Push(S2, '#');
while(S->ch[i] != '\0')
{
if(isOperator(S->ch[i]) == 1)
{
if(flag == 0)
{
if(S->ch[i] == '(')
{
Push(S2, S->ch[i]);
i++;
}
else
{
Push(S2, S->ch[i]);
flag++;
i++;
}
}
else
{
switch(PRI(S2->array[S2->top - 1], S->ch[i]))
{
case 1:
if(S->ch[i] == '(')
{
Push(S2, S->ch[i]);
flag = 0;
i++;
}
else if(S->ch[i] == ')')
{
Push(S1, Calc(Pop(S1), Pop(S2), Pop(S1)));
while(S2->array[S2->top-1] != '(')
{
Push(S1, Calc(Pop(S1), Pop(S2), Pop(S1)));
}
Pop(S2);
if(S2->array[S2->top - 1] == '#')
{
flag = 0;
}
printf("\n");
i++;
; }
else
{
Push(S1, Calc(Pop(S1), Pop(S2), Pop(S1)));
Push(S2, S->ch[i]);
i++;
}
break;
case -1:
if(S->ch[i] == ')')
{
Push(S1, Calc(Pop(S1), Pop(S2), Pop(S1)));
while(S2->array[S2->top-1] != '(')
{
Push(S1, Calc(Pop(S1), Pop(S2), Pop(S1)));
}
Pop(S2);
if(S2->array[S2->top - 1] == '#')
{
flag = 0;
}
i++;
}
else
{
Push(S2, S->ch[i]);
i++;
}
break;
}
}
a++;
}
else if(isOperator(S->ch[i]) == 0)
{
n[j] = S->ch[i] - '0';//把ASCLL码转化成数字
if(isOperator(S->ch[i+1]) == 1 || S->ch[i+1] == '\0')
{
Push(S1, Dushu(n, j));
j = 0;
i++;
}
else
{
j++;
i++;
b++;
}
b++;
}
else if(isOperator(S->ch[i]) != 1 || isOperator(S->ch[i]) != 0)
{
printf("Expression error!\n");
break;
}
}
if(i >= S->length - 1)
{ //表达式遍历完了之后,栈中可能还存有元素(例如:表达式中有括号),则需把栈中元素弹出并计算,直到栈空为止
while((S1->top != S1->bottom + 1) && (S2->top != S2->bottom + 1))
{
Push(S1, Calc(Pop(S1), Pop(S2), Pop(S1)));
}
if(a != 0 && b != 0)
{
printf(" = %d\n", S1->array[S1->bottom]);
}
else
{
printf("Expression error.\n\n");
}
}
return OK;
}
主方法
int main()
{
String S;
SqStack S1;
SqStack S2;
Init_Stack(&S1);
Init_Stack(&S2);
StrCreate(&S);
ParseExpression(&S1, &S2, &S);
return 0;
}
运行结果: