优先函数实现表达式计算
左/右 | + | * | ( | ) | i | # |
---|---|---|---|---|---|---|
+ | ·> | <· | <· | ·> | <· | ·> |
* | ·> | ·> | <· | ·> | <· | ·> |
( | <· | <· | <· | = | <· | |
) | ·> | ·> | ·> | ·> | ||
i | ·> | ·> | ·> | ·> | ||
# | <· | <· | <· | <· |
由优先表构造优先函数
优先函数 | + | * | ( | ) | i | # |
---|---|---|---|---|---|---|
f | 6 | 8 | 2 | 8 | 8 | 1 |
g | 4 | 7 | 9 | 2 | 9 | 1 |
本程序使用C语言编写
支持整数加减乘除带括号的运算
核心部分和数据结构中利用栈实现表达式运算几乎相同
程序的难点在于优先级<、=、>分类讨论
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
//优先函数
int fplus = 6;
int gplus = 4;
int fmul = 8;
int gmul = 7;
int fleft = 2;
int gleft = 9;
int fright = 8;
int gright = 2;
int fi = 8;
int gi = 9;
int fpound = 1;
int gpound = 1;
char expression[128];
int flag = 1;
void Error()
{
printf("错误\n");
exit(0);
}
void Input()
{
//char over[] = {'#', '\0'};
printf("请输入表达式,以#结尾:");
gets(expression);
//printf("Input: %s\n",expression);
}
int f(char opt)
{
if(opt == '+' || opt == '-')
{
return fplus;
}
else if (opt == '*' || opt == '/')
{
return fmul;
}
else if (opt == '(')
{
return fleft;
}
else if (opt == ')')
{
return fright;
}
else if (opt == 'i')
{
return fi;
}
else if (opt == '#')
{
return fpound;
}
return -1;
}
int g(char opt)
{
if(opt == '+' || opt == '-')
{
return gplus;
}
else if (opt == '*' || opt == '/')
{
return gmul;
}
else if (opt == '(')
{
return gleft;
}
else if (opt == ')')
{
return gright;
}
else if (opt == 'i')
{
return gi;
}
else if (opt == '#')
{
return gpound;
}
return -1;
}
int In(char num)
{
if(num == '0' ||num == '1' || num == '2' || num == '3' || num == '4' ||
num == '5'|| num == '6' || num == '7' || num == '8' || num == '9')
return 1;
else
return -1;
}
int Operation(int a, char opt, int b)
{
switch(opt)
{
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
default : return 0;
}
}
int main()
{
int index_e = 0; // 字符串下标
int index_oprt = 0; // 算符栈下标
int index_opnd = 0; // 算量栈下标
int Sn[100];
char Sp[100];
int num1;
int num2;
char temp[100];
Sp[0] = '#';
Input();
//printf("算符栈: %s\n",Sp);
while( flag == 1 )
{
int t = 0;
if( Sp[index_oprt] == '#' && expression[index_e] == '#' )
{
//printf("都为#,结束\n");
flag = 0;
}
else if(Sp[index_oprt] == '(' && expression[index_e] == ')')
{
//printf("读到括号\n");
index_oprt--;
index_e++;
}
else if(In(expression[index_e]) == 1)
{
//printf("读到数字\n");
while(In(expression[index_e]) == 1)
{
temp[t] = expression[index_e];
t++;
index_e++;
}
//printf("temp: %s\n",temp);
//atof()是把字符串转换成double
Sn[index_opnd++] = atof(temp);
//printf("number %d\n",Sn[index_opnd-1]);
//清空temp
for(int m=0; m<100; m++)
temp[m] = '\0';
}
else if(f(Sp[index_oprt]) < g(expression[index_e]))
{
//printf("%d %d\n",f(Sp[index_oprt]),g(expression[index_e]));
//printf("小于\n");
Sp[index_oprt + 1] = expression[index_e];
index_oprt++;
index_e++;
//printf("%c 入栈\n",Sp[index_oprt]);
}
else if(f(Sp[index_oprt]) > g(expression[index_e]))
{
//printf("大于\n");
//出栈两个数
num2 = Sn[index_opnd - 1];
index_opnd--;
num1 = Sn[index_opnd - 1];
index_opnd--;
//算符栈出一个,算完了结果再入算量栈
Sn[index_opnd] = Operation(num1, Sp[index_oprt], num2);
index_opnd++;
index_oprt--;
}
else
{
Error();
}
}
printf("表达式的值为:%d\n", Sn[0]);
return 0;
}
运行截图: