计算机的本质工作就是做数学运算,那计算机能够读入字符串"1+2+3+4+5+6+7"并计算值吗?
答案是肯定的。
这里我基本实现了个位数的加减乘除。当然这个算法最简单的解决方案是採用二叉树(后面会实现~)。这里作出了栈的实现方式。
首先引入两个概念:
中缀表达式和后缀表达式
1,在生活中我们通常书写1+1的时候都会写成1+1,废话~。这就是中缀表达式。更符合人们的思维习惯与想法。
2,所谓后缀表达式就是将运算符写在操作数的后面,这样更符合计算机的思维。
举例:
5 + 3 => 5 3 +
1 + 2 * 3 => 1 23 * +
9 + ( 3 – 1 ) * 5 => 9 3 1 – 5 * +
为什么会这种呢?我来用我的大白话作一下解释。比方 9 + ( 3 – 1 ) * 5 => 9 3 1 – 5 * +
后缀表达式在实现计算的时候,遇到符号就向左寻找操作数。比方上面的9 3 1后面就有 - 号,此时计算机就会将3作为左操作数。1作为右操作数,也就是计算3-1的值。继续前进,遇到5 pass,遇到*号,就会将刚刚计算好的3-1的值作为左操作数。5作为右操作数,即为(3-1)*5,继续前进。遇到+号,就会计算9+(3-1)*5的值。就是这样~
那么计算机是怎样将中缀表达式转换为后缀表达式和怎样将后缀表达式的值求出来的呢?
中缀转后缀:
遍历中缀表达式中的数字和符号
对于数字:直接输出
对于符号:
->左括号:进栈
->符号:与栈顶符号进行优先级比較
栈顶符号的优先级低:符号进栈
栈顶符号的优先级高:将栈顶符号弹出并输出,之后进栈
->右括号:将栈中的全部符号弹出并输出
计算后缀的值:
遍历后缀表达式中的数字和符号
对于数字:进栈
对于符号:
->从栈中弹出右操作数
->从栈中弹出左操作数
->依据符号进行运算
->将运算结果压入栈中
遍历结束:栈中的唯一数字为计算结果
好了,我们来用代码实现下面,跟上一篇一样,这里相同须要用到栈的代码,相同这里就不再贴了,请參阅: 栈的实现与操作(C语言实现)。
// 栈的应用计算表达式.cpp : 定义控制台应用程序的入口点。// #include "stdafx.h" #include <memory.h> #define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include "LinkStack.h" #include <malloc.h> //推断是否为数字 int isNumber(char c) { return ('0' <= c) && (c <= '9'); } //推断是否为操作符 int isOperator(char c) { return (c == '+') || (c == '-') || (c == '*') || (c == '/'); } //推断是否为:( int isLeft(char c) { return (c == '('); } //推断是否为:) int isRight(char c) { return (c == ')'); } //比較优先级 int priority(char c) { int ret = 0; if( (c == '+') || (c == '-') ) { ret = 1; } if( (c == '*') || (c == '/') ) { ret = 2; } return ret; } //输出 void output(char c) { if( c != '