本来一个建造两个结构体,一个用于定义操作码栈,类型为字符,一个用于定义操作数栈,但是比较懒,就用了一个结构体,所以代码
/* 由于采用了getchar获得数据,因此所有结果都是以ASCII码显示,且只能读取0~9
//显示的结果只有在-176~80,超过范围则结果不正确
//改进方法:单独建立一个新的操作数栈或者链表形式(不合要求)
//在操作数位置输入操作符%c,在操作符位置输入操作数%d,但是有括号时,存在问题,连续的操作符会错乱
*/
//代码如下:
//结构体定义、栈弹出压入代码则不多写了。
void Eva_expre() //表达式求值
{
printf("请输入表达式:");
SqStack OPTR,OPND; //定义栈
SElemtype x,c,op,a,b;
int res;
InitStack(OPTR); //算符栈
InitStack(OPND); //操作数栈
Push(OPTR, '#'); //终止符
x = GetTop(OPTR);
c = getchar();
while (x != '#' || c != '#') //起始符和终止符没有相遇
{
if (judge_op(c)) //判断c是否为操作数
switch (judge_OP_priority(c,x))
{
case '<': //栈顶元素优先级低
Push(OPTR, c);
c = getchar();
break;
case '=': //去除括号
Pop(OPTR, op);
c = getchar();
break;
case '>': //栈顶元素优先级高
Pop(OPTR, op);
Pop(OPND, b);
Pop(OPND, a);
res = Operator(a-48, op, b-48); //a和b是ASCII码
res += 48;
Push(OPND, res);
break;
default:
break;
}
else
{
Push(OPND, c); //压栈
c = getchar();
}
x = GetTop(OPTR); //复制一个出来对比,不弹出
}
printf("result is:%d\n", GetTop(OPND) - 48); //实现个位数的相加减乘除,且结果只限于127以内
}
char judge_OP_priority(char op1, char op2) //判断算符优先级
{
char Oporder[7] = {'+','-','*','/','(',')','#'}; //算符顺序
char OPlevelform[7][7] = {
{'>', '>', '<', '<', '<', '>', '>'},
{'>', '>', '<', '<', '<', '>', '>'},
{'>', '>', '>', '>', '<', '>', '>'},
{'>', '>', '>', '>', '<', '>', '>'},
{'<', '<', '<', '<', '<', '=', '!'},
{'>', '>', '>', '>', '!', '>', '>'},
{'<', '<', '<', '<', '<', '!', '='}}; //算符间的优先关系
int m,n;
m = 0;
n = 0;
while (op1 != Oporder[m])
m++;
while(op2 != Oporder[n])
n++;
return OPlevelform[n][m]; //返回优先结果
}
bool judge_op(char op) //判断是否是算符
{
if (op == '+' || op == '-' || op == '*' || op == '/' || op == '(' || op == ')' || op == '#')
{
return 1; //为算符返回1
}
return 0;
}
int Operator(int a, char op, int b) //计算函数
{
switch (op)
{
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
default:
return 0;
}
}
int judgedigit(int num) //判断位数函数
{
int count = 0;
while(num > 0)
{
num/=10;
count++;
}
return count;
}