算法与程序实践2(递归2)

2018-12-21 13:48

《算法与程序实践2》习 题 解 答8——递归2

CS81:菲波那契数列

(来源:poj.grids.cn 2753,程序设计导引及在线实践(李文新)例9.2 P198) 问题描述:

菲波那契数列是指这样的数列: 数列的第一个和第二个数都为1,接下来每个数都等于前面2个数之和。

给出一个正整数a,要求菲波那契数列中第a个数是多少。 输入:

第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数a(1 <= a <= 20)。 输出:

输出有n行,每行输出对应一个输入。输出应是一个正整数,为菲波那契数列中第a个数的大小。 样例输入: 4 5 2 19 1

样例输出:

5 1 4181 1

解题思路:

这个题目要求很明确,因为a的规模很小,所以递归调用不会产生栈溢出的问题。设第n 项值为f(n),则f(n) = f(n-1)+f(n-2)。已知f(1)=1,f(2)=1 ,则从第3项开始,可以用公式求。

参考程序:

#include

int f(int a) { if(a==1 || a==2) return 1; return f(a-1)+f(a-2); }

int main() { int n;

int i; scanf(\ for(i=1;i<=n;i++) { int a; scanf(\ printf(\ } return 0; }

#include #define N 20 int fi[N]; int f(int n) {

if(fi[n]!=-1) return fi[n]; if(n==0) return 0; else if(n==1) return 1; else {

fi[n]=f(n-1)+f(n-2); return fi[n]; } }

int main() { int n; int i; scanf(\ for(i=0;i

CS82:二叉树

(来源:poj.grids.cn 2756,程序设计导引及在线实践(李文新)例9.3 P199) 问题描述:

图8-1 满二叉树

如图8-1所示,由正整数1, 2, 3, ...组成了一棵无限大的二叉树。从某一个结点到根结点(编号是1的结点)都有一条唯一的路径,比如从10到根结点的路径是(10, 5, 2, 1),从4到根结点的路径是(4, 2, 1),从根结点1到根结点的路径上只包含一个结点1,因此路径就是(1)。对于两个结点x和y,假设他们到根结点的路径分别是(x1, x2, ... ,1)和(y1, y2, ... ,1)(这里显然有x = x1,y = y1),那么必然存在两个正整数i和j,使得从xi 和 yj开始,有xi = yj , xi + 1 = yj + 1, xi + 2 = yj + 2,... 现在的问题就是,给定x和y,要求xi(也就是yj)。 输入:

输入只有一行,包括两个正整数x和y,这两个正整数都不大于1000。 输出:

输出只有一个正整数xi。

样例输入: 10 4

样例输出: 2

解题思路: 这个题目要求树上任意两个节点的最近公共子节点。分析这棵树的结构不难看出,不论奇数偶数,每个数对2做整数除法,就走到它的上层结点。

我们可以每次让较大的一个数(也就是在树上位于较低层次的节点)向上走一个结点,直到两个结点相遇。如果两个节点位于同一层,并且它们不相等,可以让其中任何一个先往上走,然后另一个再往上走,直到它们相遇。设common(x, y) 表示整数x 和y 的最近公共子节点,那么,根据比较x 和y 的值,我们得到三种情况:1) x 与y 相等,则common(x,

y) 等于x 并且等于y;2)x 大于y,则common(x, y) 等于common(x/2, y); 3)x 小于y,则common(x, y) 等于common(x,y/2);

参考程序:

#include

int common(int x,int y) { if(x==y) return x; if(x>y) return common(x/2,y); return common(x,y/2); }

int main() { int m,n; scanf(\ printf(\ return 0; }

注意事项:

问题一:有一种比较直观的解法是对于两个给定的数,分别求出它们到根节点的通路上的所有节点的值,然后再在两个数组中寻找数码最大的公共节点。这种做法的代码比较繁琐,容易在实现中出错;

问题二:代码实现逻辑不明晰,造成死循环等错误,例如,有人只将其中一个数不停地除以2,而不理会另外一个数。

CS83:波兰表达式

(来源:poj.grids.cn 2694,程序设计导引及在线实践(李文新)例9.4 P201) 问题描述:

波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的波兰表示法为+ 2 3。波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的波兰表示法为* + 2 3 4。本题求解波兰表达式的值,其中运算符包括+ - * /四个。 输入:

输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数。 输出:

输出为一行,表达式的值。

可直接用printf(\输出表达式的值v。 样例输入:

* + 11.0 12.0 + 24.0 35.0

样例输出:

1357.000000 预备知识:

逆波兰表达式的用途:

它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。其运算方式如下: 按顺序扫描逆波兰表达式,如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。

中序表达式转换为逆波兰表达式:

1、建立运算符栈stackOperator用于运算符的存储,此运算符在栈内遵循越往栈顶优先级越高的原则。

2、预处理表达式,正、负号前加0(如果一个加号(减号)出现在最前面或左括号后面,则该加号(减号)为正负号)。

3、顺序扫描表达式,如果当前字符是数字(优先级为0的符号),则直接输出该数字;如果当前字符为运算符或括号(优先级不为0的符号),则判断第4点 。

4、若当前运算符为'(',直接入栈;

? 若为')',出栈并顺序输出运算符直到遇到第一个'(',遇到的第一个'('出栈但不

输出;

? 若为其它,比较stackOperator栈顶元素与当前元素的优先级:

? 如果栈顶元素是'(',当前元素入栈;

? 如果栈顶元素 >= 当前元素,出栈并顺序输出运算符直到栈顶元素 < 当

前元素,然后当前元素入栈;]

? 如果栈顶元素 < 当前元素,直接入栈。

5、重复第3点直到表达式扫描完毕。 6、顺序出栈并输出运算符直到栈元素为空。

举例说明:

表达式\,将中缀表达式转换为逆波兰表达式。

1)建立一个运算符栈stackOperator用来存放运算符;建立一个字符串链表reversePolishExpression用来存放逆波兰表达式

2)顺序扫描\+ ((1 + 2) * 4) ? 3\,根据算法可以得出stackOperator及reversePolishExpression值的变化过程:

扫描 操作 stackOperator值 reversePolishExpression值 注释

5 输出 空 5 当前字符是数字直接输出该数字 + 入栈 + 5 栈顶元素为空,不用比较,入栈 ( 入栈 ( 5 当前运算符为'(',直接入栈 ( 入栈 ( ( 5 当前运算符为'(',直接入栈 1 输出 ( ( 5 1 当前字符是数字直接输出该数字 + 入栈 ( ( + 5 1 + 优先级< 栈顶元素 ( ,入栈 2 输出 ( ( + 5 1 2 当前字符是数字直接输出该数字


算法与程序实践2(递归2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:论大学生诚信考试的制度建设

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: