上次写了一个逆波兰表达式的求值代码,但要求是将表达式用数组来表示,非常的不方便!!!
大家可以参考一下:https://blog.csdn.net/code_zx/article/details/80813110
于是乎,我在上面做了一点点优化,将表达式用字符串表示,另外,数据与数据之间,数据与操作符之间,操作符与操作符之间均采用空格隔开!
话不多说,我们需要求值的表达式为:ptr = “12 3 4 + * 6 - 8 2 / -”
将比较之前数组的表示,要方便很多!!!
解题思路
重点是将数据从字符型转化为整形!!!然后将数据入栈
敬上代码块:
int IsNum(char ch) //检测是否为数字字符
{
if (ch > '0' && ch < '9')
return 1;
return 0;
}
int RPNValue_OP(char* Ptr) //优化逆波兰表达式
{
assert(Ptr); //参数检测
int size = strlen(Ptr);
int i = 0;
StackD s;
StackDInit(&s, size);
int tem = 0;
for (; i < size; i++)
{
if (IsNum(Ptr[i])) //数字字符,转化为数字
{
tem = tem * 10 + Ptr[i] - '0';
}
else if(' ' == Ptr[i])
{
if (IsNum(Ptr[i - 1])) //当前字符为空格,并且前一个字符为数字,将tem入栈
{
StackDPush(&s, tem);
tem = 0;
}
}
else
{
if (StackDSize(&s) < 2) //栈中没有两个操作数
{
printf("逆波兰表达式有误,无法计算!!\n");
return 0;
}
int right = StackDTop(&s); //取出右左操作数
StackDPop(&s);
int left = StackDTop(&s);
StackDPop(&s);
switch (Ptr[i])
{
case '+':
StackDPush(&s, left + right);
break;
case '-':
StackDPush(&s, left - right);
break;
case '*':
StackDPush(&s, left * right);
break;
case '/':
if (right == 0) //被除数为零,不能计算
{
printf("逆波兰表达式被除数为零,无法计算!!!\n");
return 0;
}
else
{
StackDPush(&s, left / right);
break;
}
}
}
}
if (StackDSize(&s) != 1) //遍历完表达式后,检测栈中是否只有一个操作数,不是则有误!
{
printf("逆波兰表达式操作数过多!!\n");
return 0;
}
else //若只有一个操作数,直接返回
{
return StackDTop(&s);
}
}
测试结果
最后我要说的是
1、我还没有解决中缀表达式到后缀表达式的转化
2、我用的栈是动态栈,记得释放空间,我这儿忘了!!
3、谢谢!!