想想计算机是如何实现四则运算的呢!我们发现四则运算中的括号都是成对出现的,多重括号也都是完全嵌套匹配的。
先了解下后缀表达式和中缀表达式。我们平时使用的标准的四则运算表达式就是中缀表达式。中缀表达是的特点是:运算符都是在数字的中间,而我们需要做的就是把中缀表达式转换为后缀表达式,即,所有的符号都是在数字的后面出现的。
例如:中缀表达式:1+(2-1)*3+4/2,转换为后缀表达式则为1 2 1 - 3 * + 4 2 / +
那么如何借用栈实现转换呢?
思路:首先我们从一个数组strmid存放中缀表达式,然后从左往右遍历遍历表达式,遇到数字则输出,即成为后缀表达式的一部分;如果是符号,则判断它与栈中栈顶元素(运算符)的优先级,是右括号或优先级低于栈顶符号,则栈顶元素依次出栈并输出,接着将当前符号进栈,一直到最终输出后缀表达式为止。
①初始化一个空栈,用来对符号进出使用。
②第一个数字是1,直接输出(存入数组endstr中),成为后缀表达式的一部分。
③接着是‘+’,符号,入栈,s->top++;s->data[s->top]=‘x’;
④第3个字符是'(',左括号,还未配对,直接入栈s->top++;s->data[s->top]=‘(’;
⑤第4个字符是数字2,直接输出直接输出(存入数组endstr中);
⑥第5个字符是符号-,入栈,
⑦第6个字符是数字1,直接输出(存入数组endstr中)。
⑧第7个字符是符号')',则需要匹配此前的'(',所以栈顶元素依次出栈,并输出到数组endstr中,知道'('为止,并将栈中栈顶元素‘(’置0,s->data[s->top] = 0; s->top--;此时endstr中的元素为 1 2 1-
⑨第8个字符是*,则比较栈顶元素符号的优先级,*的优先级高于栈顶元素+的优先级,所以所以+不出栈,*入栈。接下来数字3输出到数组endstr中;接着是符号+,因为+号的优先级低于当前栈顶元素*的优先级(且没有比+优先级更低的),所以,栈中的元素全部依次出栈。即此时的emdstr为 1 2 1 - 3 * + 。接着是数字4,直接输出到endstr中,符号/,因其优先级高于栈顶元素,则入栈;数字2,输出到endstr中,最后栈中符号依次输出到endstr中,即此时endstr中元素为1 2 1 - 3 * + 4 2 / +
至此,中缀表达式转换为后缀表达式。
后缀表达式转换为结果:
①初始化一个空栈。此栈用来对要运算的数字进出使用。
②后缀表达式中的前3个都是数字,所以1、2、1入栈。
③接下来是‘-’,所以栈中的1出栈作为减数,2出栈作为被减数,并计算出2-1的结果1,将1入栈。
④接着3入栈
⑤接下来是‘*’,所以将栈中的3出栈作为乘数,1作为被乘数,计算结果等于3, 3入栈。
⑥接下来是‘+’,所以3和1出栈,计算等到4,入栈。
⑦接着4和2入栈
⑧接下来是‘/’,则2出栈作为除数,4作为被除数,计算4/2等于2, 2入栈
⑨接下来是‘+’,则将4和2出栈,计算4+2=6,将6入栈。
最后6出栈,栈变为空。
初始化栈:
1 void InitStack(stack *s) 2 { 3 int i; 4 for (i = 0; i < MAXSIZE;i++) 5 { 6 s->data[i] = 0; 7 } 8 s->top = -1; 9 return ; 10 }
测试部分:
符号( )* + ' - . / 的ASCII值分别为40、41、42、43、44、45、46、47. 通过一个一维数组将( )* + ' - . / 8个符号的优先级记录起来。( 和 )的优先级表示为table[0]和table[1]都为0,而* 和 / 优先级表示为 table[2]和table[7]都为2, +和 - 优先级表示为 table[3]和table[5]都为1.
总结:计算机处理我们输入的中缀表达式,主要是先将中缀表达式转换为后缀表达式,然后在通过后缀表达式得出结果。
2013-2-1 14:49