| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3258 人关注过本帖, 3 人收藏
标题:今天无意中发现的一个很优美的递归
只看楼主 加入收藏
龙航四海
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:58
专家分:102
注 册:2012-10-17
收藏
得分:0 
来学习,顺便捞点分,嘿嘿
2012-12-20 11:06
冰冻零点
Rank: 3Rank: 3
来 自:西安电子科技大学
等 级:论坛游侠
帖 子:81
专家分:136
注 册:2012-9-18
收藏
得分:0 
回复 21楼 beyondyf
杨大哥好!仔细看了你的代码,有个不懂的地方,想不通,请赐教
if (e * d >= c * f){ cal(a, b, c, d, n - 1 ); return ;}
这个地方,因为e/f=a/b+1/n<a/b+1/(n-1),如果(e * d >= c * f)成立,那么在n-1是也应该成立。因此我觉得写成这样就可以了
if (e * d >= c * f) return ;
但是这显然不合题意的,还没测试,望指点

好好学习,天天向上
2012-12-20 11:27
Esllovejsy
Rank: 1
等 级:新手上路
帖 子:7
专家分:0
注 册:2012-10-19
收藏
得分:0 
还没发么....

Ture will cannot be defeated.
2012-12-20 13:16
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
我最开始遇到的题目是这样的:
按顺序输出所以分母小于等于n的最简分数

他的分析如下:
利用a/b<(a+c)/(b+d)<c/d,以0/1和1/1为两端点进行递归


程序代码:
void print(int a, int b, int c, int d, int n)
{
     if (b + d > n) return;
     print(a, b, a+c, b+d, n);
     printf("%d/%d\n", a+c, b+d);
     print(a+c, b+d, c, d, n);
}

然后外部调用print(0,1,1,1,n)即可输出答案


我之前以为这个函数可以任意调用,后来发现好像是只是用于(0,1,1,1)前4个参数,如果改变了参数的话一个是得到的数不一定是最简分数,这点倒可以通过约分解决,还有一点就是(b+d>n)有时候不一定意味着递归的结束,比如调用print(1,7,8,9,10),第一步递归就会结束,显然是错误的

所以,我对于自己随手改了一下的题目无法通过对这个递归进行修改解决了,不过他之前的那个解法确实挺优美的

至于杨大哥的那个递归解法没看大懂,42的问题是因为整除时约掉了尾巴导致可以进行递归的,不过不懂为什么可以得到正确的答案,求讲解
2012-12-20 18:02
dreamfree
Rank: 1
等 级:新手上路
帖 子:17
专家分:4
注 册:2012-12-20
收藏
得分:0 
好东西,还在研究中
2012-12-20 18:23
azzbcc
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:江西财经大学
等 级:贵宾
威 望:81
帖 子:3293
专家分:12919
注 册:2012-11-4
收藏
得分:10 
程序代码:
#include<stdio.h>
void cal(int a, int b, int c, int d, int n)
{   //将区间不断分割,直到区间(a, b)满足 x/n < a < b < (x+1)/n
    //再减小n,直到满足(x+1)/n < b,然后分割、减小交替执行,
    //直到n = 0。递归下一个区间cal(e, f, c, d, n);
    //杨大哥好厉害!
    int e, f, t, t1, t2;

    if(n <= 0) return;//递归结束条件
    e = a * n / b + 1;
    //a / b = x / n;    e = [x] + 1;//保证e / n > a / b且使 e最小
    f = n;
    if(e * d >= c * f){ cal(a, b, c, d, n - 1); return;}
    //e / f >= c / d时,递归n - 1

    for(t1 = e, t2 = f; t = t1 % t2; t1 = t2, t2 = t);
    //辗转相除法求e、f最大公约数
    e /= t2;    f /= t2;

    //以e / f为分界线,分别递归左边和右边
    cal(a, b, e, f, n);
    printf("%d/%d\n", e, f);
    cal(e, f, c, d, n);
}
int main()
{
    cal(1, 2, 2, 3, 10);
    return 0;
}


[fly]存在即是合理[/fly]
2012-12-20 18:40
小小战士
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:1
帖 子:569
专家分:1313
注 册:2012-11-3
收藏
得分:0 
一直在膜拜。。。。。。

小小战士,战士中的战斗机!
2012-12-20 18:52
一个人的孤独
Rank: 2
等 级:论坛游民
帖 子:45
专家分:56
注 册:2012-10-15
收藏
得分:0 
学习
2012-12-20 19:50
qunxingw
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:贵宾
威 望:24
帖 子:1676
专家分:7295
注 册:2011-6-30
收藏
得分:0 
高手无私奉献理应获得尊敬!

www.qunxingw.wang
2012-12-20 20:02
月亮之痕
Rank: 1
等 级:新手上路
帖 子:6
专家分:4
注 册:2012-12-11
收藏
得分:0 
顶顶顶
2012-12-20 20:56
快速回复:今天无意中发现的一个很优美的递归
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023446 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved