狐狸梦见乌鸦

当坚持成为一种习惯,目标将不在遥远```
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

栈-四则运算应用

Posted on 2013-02-01 14:49  灬啊U  阅读(841)  评论(0编辑  收藏  举报

  想想计算机是如何实现四则运算的呢!我们发现四则运算中的括号都是成对出现的,多重括号也都是完全嵌套匹配的。

  先了解下后缀表达式和中缀表达式。我们平时使用的标准的四则运算表达式就是中缀表达式。中缀表达是的特点是:运算符都是在数字的中间,而我们需要做的就是把中缀表达式转换为后缀表达式,即,所有的符号都是在数字的后面出现的。

  例如:中缀表达式: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