我们正常平时使用的表达式是中序/中缀表达式,即运算符在数字中间,中缀的缺点:需要考虑符号的优先级。
+123 456:波兰式/前置表达式
123 456+:逆波兰式/后缀表达式
做法:
1.对表达式进行扫描,遇到运算符时就入栈,数字就不管。
2.运算符之间入栈和出栈依赖优先级情况,优先级高的就入栈,低的就先将栈内高优先级出栈后进行入栈
()中间的一定入栈。小括号的处理:左一定进,右一定不进,直到出栈时,右小括号遇上左小括号,相互抵消
同样的运算符,栈内的优先级比待入栈运算符优先级低,先入栈的优先级高
代码细节:
(利用空格隔开两个数字,对多位数的处理
如果是选择题,就把选项与题目的结果直接运算对比结果就好啦~
如果是填空题:通过加括号消除优先级。如果是后缀表达式就把运算符移到括号后面,前缀移到括号前面,最后把括号删除,如下图进行的后缀表达式做法所示:
如果是大题:
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <ctype.h>
#include<assert.h>
char* MidToLast(const char* str)
{
int len = strlen(str);
char* last = (char*)malloc(len * 2);//last暂时存放后缀表达式,后面会free
assert(last != NULL);
if (last == NULL)
return NULL;
//定义栈
int i = 0;
char* s = (char*)malloc(len / 2);//S:栈,为栈开辟空间
assert(s!= NULL);
if (s == NULL)
return NULL;
int top = 0;//栈顶
while (*str != '\0')
{
//1.如果是数字字符,不入栈,直接++后移
if (isdigit(*str))
{
last[i++] = *str++;
}
//2.是符号
else
{
last[i++] = ' ';//分割数字
//2.1 空栈直接入栈
if (top == 0)
{
s[top++] = *str++;
}
//2.2 不是空栈
else
{
//2.2-1 待入栈字符是左括号,且栈顶元素是右括号,括号匹配,相互抵消
if (*str == ')' && s[top - 1] == '(')
{
str++;
top--;
}
//2.2-2 栈内是小括号,则括号内的符号一定入栈
else if (s[top - 1] == '(')//
{
s[top++] = *str++;
}
//2.2-3 待入栈元素是'+' '-',则栈内元素一定优先级高,栈内出栈
else if (*str == '+' || *str == '-')//此时str不++
{
last[i++] = s[--top];//把栈顶元素给后缀表达式
}
//2.2-4 待入栈元素是'*' '/'
else if (*str == '*' || *str == '/')
{
//2.2-4-1 栈顶元素是'*' '/'时,栈顶元素出栈
if (s[top - 1] == '*' || s[top - 1] == '/')
last[i++] = s[--top];
else//否则,数组元素进栈
s[top++] = *str++;
}
//2.2-5 待入栈元素是'(',直接入栈
else
s[top++] = *str++;
}
}
}
while (top > 0)
last[i++] = s[--top];
last[i] = '\0';
free(s);
return last;
}
int main()
{
char* p = MidToLast("3+4");
printf("%s\n", p);
free(p);
return 0;
}
运行结果:
对出栈的表达式进行运算
数字入栈
遇到运算符,弹出两个栈顶元素进行运算,最上面的栈顶元素作为运算符右边,第二个栈顶元素位于运算符左边。