| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1264 人关注过本帖
标题:(分享) 递归 求组合
只看楼主 加入收藏
BlueGuy
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
结帖率:94.72%
收藏
已结贴  问题点数:20 回复次数:18 
(分享) 递归 求组合
。。。。
。。。。

[ 本帖最后由 BlueGuy 于 2011-3-10 20:39 编辑 ]
搜索更多相关主题的帖子: 分享 
2011-01-04 13:55
点线面
Rank: 8Rank: 8
来 自:NO.-1
等 级:蝙蝠侠
帖 子:525
专家分:980
注 册:2011-1-3
收藏
得分:5 
运行时程序结果只有这些吗
1 2 3 4
1 2 3 5
1 2 4 5
1 3 4 5
2 3 4 5
输出的结果不对啊,程序有问题,
PS:我不会用递归排序,很麻烦

小代码,大智慧
2011-01-04 14:18
BlueGuy
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
收藏
得分:0 
以下是引用点线面在2011-1-4 14:18:56的发言:

运行时程序结果只有这些吗
1 2 3 4
1 2 3 5
1 2 4 5
1 3 4 5
2 3 4 5
输出的结果不对啊,程序有问题,
PS:我不会用递归排序,很麻烦
c(5, 4) = 5 !!!!!!!

我就是真命天子,顺我者生,逆我者死!
2011-01-04 14:26
点线面
Rank: 8Rank: 8
来 自:NO.-1
等 级:蝙蝠侠
帖 子:525
专家分:980
注 册:2011-1-3
收藏
得分:0 
哦,理解错误,想了排列去,如果要分析代码花不了时间。不过对自己有帮助。
就像
代码分析:

recursion(1)
{
      while(1<=5)
   {
    combination[1] = 1;
       recursion(2)
    }
}

recursion(2)
{
    while(2<=5)
    {
      combination[2] = 2;
      recursion(3)
    }
}

recursion(3)
{
    while(3<=5)
    {
      combination[3] = 3;
      recursion(4)
    }
}

recursion(4)
{
    while(4<=5)
    {
      combination[4] = 4;
      if(4==4)
      {
        printf();  // X,1 2 3 4
      }
    }
}继续补充ing

小代码,大智慧
2011-01-04 14:39
Devil_W
Rank: 10Rank: 10Rank: 10
等 级:青峰侠
威 望:9
帖 子:1160
专家分:1797
注 册:2009-9-14
收藏
得分:5 
设R={r1,r2,...,rn}是要进行排列的n个元素,Ri=R-{ri}.
集X中元素的全排列记为Perm(X),
(ri)Perm(X)表示在全排列Perm(X)的每一个排列前加上前缀ri得到的排列.
R的全排列可归纳定义如下:
  当n=1时,Perm(R)={r},r是集合R中唯一的元素.
  当n>1时,Perm(R)由(r1)Perm(R1),(r2)Perm(R2),....(rn)Perm(Rn)构成


引用定义。
2011-01-04 14:46
qq1023569223
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:湖南科技大学
等 级:贵宾
威 望:26
帖 子:2753
专家分:13404
注 册:2010-12-22
收藏
得分:5 
//能够帮助到大家, 就算失业我也开心
楼主真是高尚啊,赞一个


   唯实惟新 至诚致志
2011-01-04 14:48
点线面
Rank: 8Rank: 8
来 自:NO.-1
等 级:蝙蝠侠
帖 子:525
专家分:980
注 册:2011-1-3
收藏
得分:0 
代码分析:

recursion(1)
{
      while(1<=5)
   {
    combination[1] = 1;
       recursion(2)
    }
}

recursion(2)   //recursion(1)要压栈,记录 i=1,还没有执行
完,因为for()还没有结束循环
{
    while(2<=5)
    {
      combination[2] = 2;
      recursion(3)
    }
}

recursion(3)   //recursion(2)要压栈,记录 i=2,还没有执行
完,因为for()还没有结束循环
{
    while(3<=5)
    {
      combination[3] = 3;
      recursion(4)
    }
}

recursion(4)     //recursion(3)要压栈,记录 i=3,还没有执
行完,因为for()还没有结束循环
{
    while(4<=5)
    {
      combination[4] = 4;
      if(4==4)
      {
        printf();  //    开始打印 1 2 3 4
      }
    }
}

recursion(4)  // 继续执行循环,直到循环结束
{
    while(5<=5)
    {
      combination[4] = 5; //0,1 2 3 5
      if(4==4)
      {
        printf();  //  开始打印  1 2 3 5
      }
    }
}

recursion(4) //循环结束  

recursion(3)   //之前压栈,现在退栈,结束上次循环,i现在为
4,原因是循环还没有结束
{
    while(4<=5)  //i之前是3
    {
      combination[3] = 4; //0,1 2 4 5
      recursion(4)
    }
}

recursion(4)   //recursion(3)要继续压栈,记录 i=4,还没有
执行完,因为for()还没有结束循环
{
    while(4<=5)
    {
      combination[4] = 4;  // 0, 1 2 4 4
      if(4==4)
      {
        if(k!=4)
      }
    }
}

recursion(4)  // 继续执行循环,直到循环结束,且打印数据
{
    while(5<=5)
    {
      combination[4] = 5;  // 0, 1 2 4 5
      if(4==4)
      {
       printf();  //   1 2 4 5
      }
    }
}

recursion(4) //循环结束

recursion(3)   //之前压栈,现在退栈,结束上次循环,i现在为
5,原因是循环还没有结束
{
    while(5<=5)  //i之前是3
    {
      combination[3] = 5; //0,1 2 5 5
      recursion(4)
    }
}

recursion(4)    //recursion(3)要继续压栈,记录 i=5,还没有
执行完,因为for()还没有结束循环
{
    while(4<=5)
    {
      combination[4] = 4;  // 0, 1 2 5 4
      if(4==4)
      {
        if(k!=4)
      }
    }
}

recursion(4)  // 继续执行循环,直到循环结束
{
    while(5<=5)
    {
      combination[4] = 5;  // 0, 1 2 5 5
      if(4==4)
      {
       if(k!=4)
      }
    }
}

recursion(4) //循环结束
recursion(3) //弹出recursion(3),但循环结束

recursion(2) //之前压栈,现在退栈,结束上次循环,i现在为
3,原因是循环还没有结束
{
    while(3<=5)   //之前是i=2
    {
      combination[2] = 3; // 0,1 3 5 5
      recursion(3);
    }
}
PS:单单函数执行都有156次,实在没有充分完全表达出来,递归过程大家过程应该明白吧

[ 本帖最后由 点线面 于 2011-1-4 15:49 编辑 ]

小代码,大智慧
2011-01-04 15:47
马后炮
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:156
专家分:560
注 册:2010-12-17
收藏
得分:5 
实验了一下果然是156次,实在想不明白,为什么只有五种结果,那个函数却调用如此离谱的多次,楼主算法没写好吧
如果是为了分享,那是否应该先把代码写好再分享?而不要乱写一个,虽然能实现但却不太值得学习的代码发出来,这样会误导新人

樱之雪,晓之车
2011-01-04 16:03
点线面
Rank: 8Rank: 8
来 自:NO.-1
等 级:蝙蝠侠
帖 子:525
专家分:980
注 册:2011-1-3
收藏
得分:0 
以下是引用马后炮在2011-1-4 16:03:09的发言:

实验了一下果然是156次,实在想不明白,为什么只有五种结果,那个函数却调用如此离谱的多次,楼主算法没写好吧
如果是为了分享,那是否应该先把代码写好再分享?而不要乱写一个,虽然能实现但却不太值得学习的代码发出来,这样会误导新人
我刚刚写一部分分析过程,希望顺我的分析过程看一看,或者有所收获,归递的确很简洁,不过分析起来一塌胡涂,归递本身效率就是不高,有眼看的,如果LS不怕麻烦,可以自己从头分析一次。

[ 本帖最后由 点线面 于 2011-1-4 16:11 编辑 ]

小代码,大智慧
2011-01-04 16:09
马后炮
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:156
专家分:560
注 册:2010-12-17
收藏
得分:0 
不见得递归简洁吧?
我改写了一个版主写的穷举组合的代码:

程序代码:
int next_combination(int* pArray, int nLen, int nSel)
{
    if (pArray[nLen - 1] + 1 < nSel)
    {
        ++pArray[nLen - 1];
        return 1;
    }
    else
    {
        int it = 2;
        while (it <= nLen && pArray[nLen - it] + it == nSel)
            ++it;
        if (it <= nLen)
        {
            int i;
            pArray[nLen - it]++;
            for (i = nLen - it + 1; i < nLen; ++i )
                pArray[i] = pArray[i - 1] + 1;
            return 1;
        }
        else
            return 0;
    }
}

#include <stdio.h>

int main()
{
    int arrmap[] = {1, 2, 3, 4, 5};
    int arr[20];
    int len = 4, i;

    for (i = 0; i < len; ++i) arr[i] = i; //初始化数组

    do //枚举组合的循环
    {
        for (i = 0; i < len; ++i) //打印组合
        {
            printf("%d ", arrmap[arr[i]]);
        }
        puts("");
    } while ( next_combination(arr, len, sizeof(arrmap) / sizeof(int)) ); //获取下一个组合
    scanf("%*s");
    return 0;
}


这个程序结构清晰很多啊
不过我是觉得,是楼主写的代码不好,调用这么多次简直有点莫名其妙

樱之雪,晓之车
2011-01-04 16:35
快速回复:(分享) 递归 求组合
数据加载中...
 
   



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

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