【数据结构】前缀后缀表达式求值
2018-03-13 21:18
567 查看
前缀表达式和后缀表达式是什么呢?
对于任何算数表达式来说,如果每个操作符跟在它的两个操作数之后,而不是两个操作数之间,那么这个表达式就是后缀表达,又称为逆波兰表达式,如:
3 5 + 7 * 1 -
如果是跟在两个操作数之间,那么这个表达式就是中缀表达式,如:
(3 + 5) * 7 - 1
如果是在两个操作数之前,那么这个表达式就是前缀表达式,又称波兰表达式,如:
-*+3 5 7 1
前缀表达式求值,思路如下:
因为前缀表达式,操作符肯定都在前面,因此把操作符一一入栈:
然后,如果遇到数字了,就把取出一个操作符,再得到两个操作数,进行处理然后继续循环,直到所有的操作数都处理完毕
代码如下:
注意,我这里的数字都是个位数字,我就不改这段代码了,如果遇到两位以上的数字可以用以下这段代码:
前缀表达式的递归求法:
中缀表达式的求表达式我没写,但是有中缀表达式转换后缀表达式:
例如这个中缀表达式:(3 + 5) * 7 - 1 ,要想转换成后缀表达式,就是遇到操作符就先保存起来,如果接下来遇到‘)’符号,再把保存起来的操作符加上去,然后就继续循环直到表达式结束
后缀表达式求值也是用到栈,如果遇到操作数就把操作数压栈,如果遇到操作符就出栈两个操作数然后运算再把运算后的值压入到栈里,再继续遍历表达式,直到表达式完成,栈顶元素(也是栈里唯一的元素)就是求出的值
代码如下:
这里跟前缀是一样的,如果数字是两位或者三位就用上面那个循环,如果是遇到空格了也用一个循环跳过空字符,比如:
这里只是简单的写了一下前缀后缀的求值,包括中缀转后缀,好多地方可能会有一些bug,但是大体上思路就是这样
对于任何算数表达式来说,如果每个操作符跟在它的两个操作数之后,而不是两个操作数之间,那么这个表达式就是后缀表达,又称为逆波兰表达式,如:
3 5 + 7 * 1 -
如果是跟在两个操作数之间,那么这个表达式就是中缀表达式,如:
(3 + 5) * 7 - 1
如果是在两个操作数之前,那么这个表达式就是前缀表达式,又称波兰表达式,如:
-*+3 5 7 1
前缀表达式求值,思路如下:
因为前缀表达式,操作符肯定都在前面,因此把操作符一一入栈:
然后,如果遇到数字了,就把取出一个操作符,再得到两个操作数,进行处理然后继续循环,直到所有的操作数都处理完毕
代码如下:
int PreFix(SeqStack* seq,char* str) { if (seq == NULL || str == NULL) { return; } int num1 = 0; int num2 = 0; int flag = 0; //循环处理直到遍历完表达式 while (*str != '\0') { if (*str == '-' || *str == '+' || *str == '*') { SeqStackPush(seq, *str); } else { if (flag == 0) { //由于不知道咋处理,所以我设了一个标志,只有第一次是从表达式中获取两个操作数的 num1 = *str - '0'; num2 = *++str - '0'; flag = 1; } else { num2 = *str - '0'; } //从栈中取出操作符 char s = SeqStackTopValue(seq); SeqStackPop(seq); if (s == '+') { num1 = num1 + num2; } if (s == '-') { num1 = num1 - num2; } if (s == '*') { num1 = num1 * num2; } } str++; } return num1; } #if 1 int main() { char* str = "-*+3571"; SeqStack seq; SeqStackInit(&seq); int num = PreFix(&seq, str); printf("expcet 55, actual :%d\n", num); system("pause"); return 0; } #endif
注意,我这里的数字都是个位数字,我就不改这段代码了,如果遇到两位以上的数字可以用以下这段代码:
while(*str >= '0' && *str <= '9') { num = num*10 + (num - '0'); }
前缀表达式的递归求法:
char* str = "-*+3571"; int i; int PreFix2() { int num = 0; if (*str == '+') { str++; return PreFix2() + PreFix2(); } if (*str == '-') { str++; return PreFix2() - PreFix2(); } if (*str == '*') { str++; return PreFix2() * PreFix2(); } if (*str >= '0' && *str <= '9') { num = *str++ - '0'; } return num; }
中缀表达式的求表达式我没写,但是有中缀表达式转换后缀表达式:
例如这个中缀表达式:(3 + 5) * 7 - 1 ,要想转换成后缀表达式,就是遇到操作符就先保存起来,如果接下来遇到‘)’符号,再把保存起来的操作符加上去,然后就继续循环直到表达式结束
int main(int argc, char* argv[]) { char* a = argv[1]; int i, N = strlen(a); SeqStack seq; SeqStackInit(&seq); for (i = 0; i < N; ++i) { if (a[i] == ')') { printf("%c", SeqStackTopValue(&seq)); SeqStackPop(&seq); } if (a[i] == '+' || a[i] == '*') { SeqStackPush(&seq, a[i]); } if (a[i] >= '0' && a[i] <= '9') { printf("%c", a[i]); } } }
后缀表达式求值也是用到栈,如果遇到操作数就把操作数压栈,如果遇到操作符就出栈两个操作数然后运算再把运算后的值压入到栈里,再继续遍历表达式,直到表达式完成,栈顶元素(也是栈里唯一的元素)就是求出的值
代码如下:
int Suf_Result(SeqStack* seq1, char* exp, int size) { if (seq1 == NULL) { printf("栈指针传入错误!\n"); return 0; } if (exp == NULL) { printf("表达式为空!\n"); return 0; } if (size == 0) { return 0; } // 1.把这个表达式逆序压栈 char* str = exp + size - 1; while (str != exp) { SeqStackPush(seq1, *str); str--; } SeqStackPush(seq1, *str); int arr[12]; int sz = 0; while (!SeqStackEmpty(seq1)) { char ch = SeqStackTopValue(seq1); SeqStackPop(seq1); if (ch >= '0' && ch <= '9') { arr[sz++] = ch - '0'; } else if(ch == '+' || ch == '-' || ch == '*') { int num1 = arr[sz - 1]; sz--; int num2 = arr[sz - 1]; sz--; if (ch == '+') { arr[sz++] = num1 + num2; } else if (ch == '-') { arr[sz++] = num2 - num1; } else { arr[sz++] = num1 * num2; } } } return arr[sz - 1]; }
这里跟前缀是一样的,如果数字是两位或者三位就用上面那个循环,如果是遇到空格了也用一个循环跳过空字符,比如:
while(*str == ' ') str++;
这里只是简单的写了一下前缀后缀的求值,包括中缀转后缀,好多地方可能会有一些bug,但是大体上思路就是这样
相关文章推荐
- 中缀、前缀和后缀表达式求值问题
- 前缀表达式转后缀表达式及求值经典代码
- [数据结构] 表达式求值(转化为后缀表达式再求值或直接求值)
- 前缀、中缀、后缀表达式及其求值
- 表达式求值(前缀、中缀、后缀)
- 中缀式 变 前缀试,变后缀试,然后表达式求值
- 中缀表达式直接转换为表达式二叉树、前缀表达式、后缀表达式,表达式求值
- 中缀表达式转换为前缀及后缀表达式并求值【摘】
- 中缀表达式转换为前缀及后缀表达式并求值(java实现)
- 数据结构之中缀表达式转前缀和后缀
- 【数据结构】中缀表达式|后缀表达式|前缀表达式
- [数据结构] 表达式求值(转化为后缀表达式再求值或直接求值)
- c语言数据结构实现后缀表达式求值
- 【数据结构】栈的应用---四则运算表达式求值(中缀表达式与后缀表达式转换)
- 中缀表达式求值、后缀表达式求值、中缀转后缀、前缀
- 数据结构中前缀表达式、中缀表达式、后缀表达式
- 数据结构-前缀、中缀、后缀表达式
- 中缀表达式转换为前缀及后缀表达式并求值【摘】
- 中缀表达式转换为前缀及后缀表达式并求值【摘】
- 课程设计 栈之 后缀表达式求值 中缀表达式转后缀表达式