免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3114 | 回复: 9
打印 上一主题 下一主题

[算法] 我乘车时想到的计算组合数算法 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-22 17:03 |只看该作者 |倒序浏览
如题,抛个砖,大家拿玉砸吧,用的递归

int ComputeComb(int down, int up)
{
    if(up > down || down< 0)
    {
        fprintf(stderr,"\nError Input\n");
        return EOF;
    }
    if(up == 0 || up == down)
    {
        return 1;
    }
    return (ComputeComb(down-1,up) + ComputeComb(down-1,up-1));
}


[ 本帖最后由 文化机器人 于 2009-2-22 17:36 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-02-22 17:12 |只看该作者
是 int 还是 int *?

论坛徽章:
0
3 [报告]
发表于 2009-02-22 17:15 |只看该作者

回复 #2 emacsnw 的帖子

其实可以用 int &

论坛徽章:
0
4 [报告]
发表于 2009-02-22 17:39 |只看该作者
sorry,誊写出怪了
在车上手写的,誊写时还在想配一个main
就想出了妖蛾子;改完了,一般计算组合是用什么算法?

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11
5 [报告]
发表于 2009-02-22 17:48 |只看该作者
c(m, n) = n!/(m!*(n - m)!)

  1. int factorial(int n) /* be carefull of overflow */
  2. {
  3.     int val;

  4.     val = 1;
  5.     for (; n > 1; n--) {
  6.         val *= n;
  7.     }
  8.     return val;
  9. }

  10. int combine(int m, int n)
  11. {
  12.     return factorial(n)/(factorial(m)*factorial(n-m));
  13. }
复制代码

[ 本帖最后由 cobras 于 2009-2-22 17:54 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2009-02-22 17:55 |只看该作者
继续贴代码
#include<stdio.h>

int ComputeComb(int down, int up)
{
    if(up > down || down< 0)
    {
        fprintf(stderr,"\nError Input\n");
        return EOF;
    }
    if(up == 0 || up == down)
    {
        return 1;
    }
    return (ComputeComb(down-1,up) + ComputeComb(down-1,up-1));
}

int main(int argc, char *argv[])
{
    int answer,sta num[2];
    if(argc != 3)
    {
        fprintf(stderr"\nArgument Error\n");
        exit(1);
    }
    
    sta = sscanf(argv[1],"%d",num);
    if(!sta)
    {
        fprintf(stderr,"\nNumber 1 Error!(should be a integer)\n");
        exit(2);
    }
    sta = sscanf(argv[2],"%d",num+1);
    if(!sta)
    {
        fprintf(stderr,"\nNumber 2 Error!(should be a integer)\n");
        exit(3);
    }

    answer = ComputeComb(num[0],num[1]);
    if(answer == EOF)
    {
        fprintf(stderr,"\nNumbers range Error!\n");
        exit(4)
    }
    printf("\nthe Number of Combinations is %d.\n",answer);
}


[ 本帖最后由 文化机器人 于 2009-2-22 17:57 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2009-02-22 18:11 |只看该作者
5楼的用这样不就优化了:
  1. int Permutation(int high, int low)
  2. {
  3.         int val:

  4.         val = 1;
  5.         for(; low>0;low--)
  6.         {
  7.                 val *= high--
  8.         }

  9. int combine(int m, int n)
  10. {
  11.     return Permutation(n,m)/Permutation(m,m));
  12. }
  13. }
复制代码

[ 本帖最后由 文化机器人 于 2009-2-22 18:13 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2009-02-22 18:29 |只看该作者
这个速度应该很慢吧,而且很容易溢出。

论坛徽章:
0
9 [报告]
发表于 2009-02-23 07:21 |只看该作者
当n大一点的时候,比较有用的是求它的log.

论坛徽章:
0
10 [报告]
发表于 2009-02-23 10:26 |只看该作者

回复 #1 文化机器人 的帖子

不妨考虑一种比较好,而且不容易溢出的方法:就是对数进行素数分解,也就是说 n = p1^n1*p2^n2*......

这样,C(m,n) = (n-m+1)*...*n/(1*2*...*m) 首先对分子所有的乘数进行素数分解,然后相加;在对分母的所有乘数进行素数分解,然后相加-----两者分解和之差,就得到结果了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP