| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1264 人关注过本帖
标题:(分享) 递归 求组合
只看楼主 加入收藏
BlueGuy
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
收藏
得分:0 
以下是引用马后炮在2011-1-4 16:03:09的发言:

实验了一下果然是156次,实在想不明白,为什么只有五种结果,那个函数却调用如此离谱的多次,楼主算法没写好吧
如果是为了分享,那是否应该先把代码写好再分享?而不要乱写一个,虽然能实现但却不太值得学习的代码发出来,这样会误导新人
这种程序只会出现在考试中, 你觉得你的程序正确率高, 还是我的程序正确率高。/

我就是真命天子,顺我者生,逆我者死!
2011-01-04 16:54
BlueGuy
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
收藏
得分:0 
我反着递怕新手看不懂,
#include <stdio.h>

#define NUM 3

int a[NUM+1] = {0};

void combination(int m, int k, int depth)
{   

    int i, j;
   
    for(i = m; i >= k; i--)
    {
        a[k] = i;

        if (k == 1)
        {
            for (j = 1; j <= 3; j++)
                printf ("%d ",a[j]);
            printf ("\n");
        }
        else
        {
            combination(i-1, k-1, depth+1);
        }
    }
}

int main(void)
{
    combination(5, NUM, 0);
    getchar();
    return  0;
}




我就是真命天子,顺我者生,逆我者死!
2011-01-04 17:00
点线面
Rank: 8Rank: 8
来 自:NO.-1
等 级:蝙蝠侠
帖 子:525
专家分:980
注 册:2011-1-3
收藏
得分:0 
回马后炮,觉得好像很复杂,下面代码如何
程序代码:
#include<stdio.h>
#define N 5  //相当于C6,5的组合

int main()
{
  int i,j,a[N];

for(i=0;i<N;i++)  a[i]=i+2;

for(i=0;i<N;i++)

 {
    for(j=0;j<N;j++)
    printf("%d ",a[j]);
    puts("");
     --a[i];

 }

    for(j=0;j<N;j++)
    printf("%d ",a[j]);

  scanf("%*s");
  return 0;
}


小代码,大智慧
2011-01-04 17:21
马后炮
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:156
专家分:560
注 册:2010-12-17
收藏
得分:0 
太特殊化了,不是应该考虑任意的n选m吗?

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

太特殊化了,不是应该考虑任意的n选m吗?
你觉得还有什么更好算法,可以适合通用的!我记得有一种算法是像二进制加法一样

小代码,大智慧
2011-01-04 17:47
点线面
Rank: 8Rank: 8
来 自:NO.-1
等 级:蝙蝠侠
帖 子:525
专家分:980
注 册:2011-1-3
收藏
得分:0 
以下是引用BlueGuy在2011-1-4 17:00:53的发言:

我反着递怕新手看不懂,
#include

#define NUM 3

int a[NUM+1] = {0};

void combination(int m, int k, int depth)
{   

    int i, j;
   
    for(i = m; i >= k; i--)
    {
        a[k] = i;

        if (k == 1)
        {
            for (j = 1; j <= 3; j++)
                printf ("%d ",a[j]);
            printf ("\n");
        }
        else
        {
            combination(i-1, k-1, depth+1);
        }
    }
}

int main(void)
{
    combination(5, NUM, 0);
    getchar();
    return  0;
}
分析起来不是很好分析,太麻烦,而且容易出错。

小代码,大智慧
2011-01-04 17:58
点线面
Rank: 8Rank: 8
来 自:NO.-1
等 级:蝙蝠侠
帖 子:525
专家分:980
注 册:2011-1-3
收藏
得分:0 
程序代码:
#include <stdio.h>
         //  m选n中, n的数组      选n      总数: m
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 )  //从左向靠n修正数据,IT越大,靠左边越明显,IT越少,向中间明显一点
                pArray[i] = pArray[i - 1] + 1;
            return 1;
        }
        else
        {
            return 0;  
        }
    }
}



int main()
{
    int arrmap[] = {1, 2, 3, 4, 5,6};
    int arr[20];
    int len = 6, i;   //len相当于被选中个数

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

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

仔细考虑发觉很巧妙,我不防加得注释,让大家看明白一点
,程序思路就是首先右边不断自加量
如果右边平衡,就开始中间,慢慢向左边,而且数据不断修正,重复之前动作,直到两边平衡,就结束程序

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

小代码,大智慧
2011-01-04 22:29
马后炮
Rank: 7Rank: 7Rank: 7
等 级:黑侠
帖 子:156
专家分:560
注 册:2010-12-17
收藏
得分:0 
那个代码源自https://bbs.bccn.net/thread-330464-2-1.html的11楼
你注释的代码变成有错误了,再弄弄吧

樱之雪,晓之车
2011-01-04 23:15
BlueGuy
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
收藏
得分:0 
以下是引用马后炮在2011-1-4 16:03:09的发言:

实验了一下果然是156次,实在想不明白,为什么只有五种结果,那个函数却调用如此离谱的多次,楼主算法没写好吧
如果是为了分享,那是否应该先把代码写好再分享?而不要乱写一个,虽然能实现但却不太值得学习的代码发出来,这样会误导新人
代码我稍稍改进了一下,
不是我吹牛哈,搜遍整个互联网, 都搜不到这样的简单的递归, 不信你试试
收到的鲜花
  • Devil_W2011-01-05 10:23 送鲜花  -3朵   附言:傻x,你又犯贱了。

我就是真命天子,顺我者生,逆我者死!
2011-01-05 09:13
快速回复:(分享) 递归 求组合
数据加载中...
 
   



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

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