描述
LISP语言唯一的语法就是括号要配对。
形如 (OP P1 P2 …),括号内元素由单个空格分割。
其中第一个元素OP为操作符,后续元素均为其参数,参数个数取决于操作符类型
注意:参数 P1, P2 也有可能是另外一个嵌套的 (OP P1 P2 …)
当前OP类型为add/sub/mul/div(全小写),分别代表整数的加减乘除法。简单起见,所以OP参数个数为2
举例:
- 输入:(mul 3 -7)输出:-21
- 输入:(add 1 2) 输出:3
- 输入:(sub (mul 2 4) (div 9 3)) 输出 :5
- 输入:(div 1 0) 输出:error
解决方案
众所周知,应用程序中运行的时候会有各种各样的函数的嵌套调用,甚至是递归,整个函数调用的路径(调用链)是以栈(称之为调用栈)的形式保存,异常的时候打印(或者coredump的时候来记录的吐核)都会记录逐层的调用栈信息。为什么函数逐层深入调用完毕之后能回到原来的调用点呢,就是一个配对的问题。配对也就是有明确的固定的格式来区别起始位置和结束位置,比如函数的调用入口就是起始位置,函数返回就是结束位置。针对配对的问题,可以用栈(stack)这种数据结构解决,具体的解决思路:
- 开始调用symbol-1,起始位置symbol-1-starting压栈
- symbol-1中调用symbol-2,起始位置symbol-2-starting压栈
- symbol-2调用完毕,结束位置symbol-2-ending,栈顶是symbol-2-starting,弹栈进行处理
- symbol-1调用完毕,结束位置是symbol-1-ending,栈顶是symbol-1-starting,弹栈进行处理
- 调用整个过程也完毕,调用栈也是空栈
举个栗子
举个很常见的例子,斐波那契数列:
// 数列前两项是1,后面的每一项是前面两项的和
Fib(n) = {
1, 1, 2, 3, 5, 8, 13, 21, ...}
用代码程序的话,描述(描述语言:C/C++)如下:
// 计算第count个斐波那契数列的元素
int Fib(const int& count)
{
if(count < 1)
return -1; // 输入有误
else if(count < 3)
return