这个代码想了好久还是没想通

请问一下这个递归和逆波兰式的结合的代码到底是怎么一个字符一个字符运行的啊,想了好久还是没想通

img

img

对前缀表达式求值,要从右至左扫描表达式,首先从右边第一个字符开始判断,若当前字符是数字则一直到数字串的末尾再记录下来,若为运算符,则将右边离得最近的两个“数字串”作相应运算,然后以此作为一个新的“数字串”并记录下来;扫描到表达式最左端时扫描结束,最后运算的值即为表达式的值。

所以你的程序是,输入x,递归下去(相当于入栈),然后又输入了+,再次递归下去,接着输入了11,把它转成数字返回,输入12同样转成数字返回,此时由+引起的两次递归结束,返回11+12结果为23给x引起的第一个递归,但是又输入了+,又会两次递归,把后面输入24和35转为数字,返回24+35为59结果给x引起的第二个递归。此时x的两次递归结束,返回23*59的结果为1357给main函数。

按输入顺序:

  1. x : 乘法运算,进入 exp()*exp() 分支,并进入乘号左边的 exp() 函数;
  2. + : 加法运算,再进入 exp()+exp() 分支,并进入加号左边的 exp() 函数;
  3. 11.0 :非运算符号,用atof(s)将字符串转化为浮点数并返回,返回后第2步的表达式就会变成11.0+exp(),此时再进入后面的exp()函数;
  4. 12.0 :非运算符号,同上,转化为浮点数并返回后第2步表达式变为11.0+12.0;
  5. 计算11.0+12.0并返回,返回后第1步的表达式就会变成 23.0*exp(),此时再进入后面的exp()函数;
  6. + :加法运算,再进入 exp()+exp() 分支,并进入加号左边的 exp() 函数;
  7. 24.0 :同第3步的处理一样;
  8. 35.0 :同第4步的处理一样;
  9. 第5步一样处理,最后第1步的表达式中两个exp()都被运算出的数代替,变成 23.0*59.0;
  10. 计算 23.0*59.0,得出结果为1357.0,并将此结果返回到main函数的exp()处;
  11. main函数通过 printf("%lf", 1357.0) 函数将结果打印出来。

“给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门!
递归函数关注以下几个因素
·退出条件
·参数有哪些
·返回值是什么
·局部变量有哪些
·全局变量有哪些
·何时输出
·会不会导致堆栈溢出

(1)表达式求的是 (11.0+12.0)(24.0+35.0)= 1357.0
(2)波兰式写法(
(+11.0 12.0)(+24.0 35.0))
(3)求两个数(用A和B代替)的乘积所以先输入 * ,但 A 和 B 分别是两个数的和(用a1 a2 b1 b2表示)。所以输入 + a1 a2 和 + b1 b2;
(4)递归函数解决了当输入是‘运算符’时计算后面输入的数字。

非常简单,如果是运算符,就再读取两个表达式进行计算,返回它的结果,如果是数字直接转为浮点型返回。
波兰表达式本来就是递归定义的,这样的递归调用,你可以把它想象成一个二叉树。

你这是波兰表达式,逆波兰表达式的运算符在数的后面

转换为浮点数返回

这种是递归调用的写法