gpt4 book ai didi

c++ - C++中的组合数(N选R)

转载 作者:可可西里 更新时间:2023-11-01 16:25:34 24 4
gpt4 key购买 nike

在这里,我尝试用 C++ 编写一个程序来查找 NCR。但是我的结果有问题。这是不正确的。你能帮我找出程序中的错误吗?

#include <iostream>
using namespace std;
int fact(int n){
if(n==0) return 1;
if (n>0) return n*fact(n-1);
};

int NCR(int n,int r){
if(n==r) return 1;
if (r==0&&n!=0) return 1;
else return (n*fact(n-1))/fact(n-1)*fact(n-r);
};

int main(){
int n; //cout<<"Enter A Digit for n";
cin>>n;
int r;
//cout<<"Enter A Digit for r";
cin>>r;
int result=NCR(n,r);
cout<<result;
return 0;
}

最佳答案

你的公式完全错误,应该是fact(n)/fact(r)/fact(n-r) ,但这反过来又是一种非常低效的计算方法。

参见 Fast computation of multi-category number of combinations尤其是我对那个问题的评论。 (哦,请也重新打开那个问题,这样我才能正确回答)

单拆分的情况其实很容易处理:

unsigned nChoosek( unsigned n, unsigned k )
{
if (k > n) return 0;
if (k * 2 > n) k = n-k;
if (k == 0) return 1;

int result = n;
for( int i = 2; i <= k; ++i ) {
result *= (n-i+1);
result /= i;
}
return result;
}

演示:http://ideone.com/aDJXNO

如果结果不合适,可以计算对数和,得到不精确为double的组合数。或者使用任意精度的整数库。


我将我的解决方案放在此处解决另一个密切相关的问题,因为 ideone.com 最近一直在丢失代码片段,而另一个问题仍未提供新答案。

#include <utility>
#include <vector>

std::vector< std::pair<int, int> > factor_table;
void fill_sieve( int n )
{
factor_table.resize(n+1);
for( int i = 1; i <= n; ++i )
factor_table[i] = std::pair<int, int>(i, 1);
for( int j = 2, j2 = 4; j2 <= n; (j2 += j), (j2 += ++j) ) {
if (factor_table[j].second == 1) {
int i = j;
int ij = j2;
while (ij <= n) {
factor_table[ij] = std::pair<int, int>(j, i);
++i;
ij += j;
}
}
}
}

std::vector<unsigned> powers;

template<int dir>
void factor( int num )
{
while (num != 1) {
powers[factor_table[num].first] += dir;
num = factor_table[num].second;
}
}

template<unsigned N>
void calc_combinations(unsigned (&bin_sizes)[N])
{
using std::swap;

powers.resize(0);
if (N < 2) return;

unsigned& largest = bin_sizes[0];
size_t sum = largest;
for( int bin = 1; bin < N; ++bin ) {
unsigned& this_bin = bin_sizes[bin];
sum += this_bin;
if (this_bin > largest) swap(this_bin, largest);
}
fill_sieve(sum);

powers.resize(sum+1);
for( unsigned i = largest + 1; i <= sum; ++i ) factor<+1>(i);
for( unsigned bin = 1; bin < N; ++bin )
for( unsigned j = 2; j <= bin_sizes[bin]; ++j ) factor<-1>(j);
}

#include <iostream>
#include <cmath>
int main(void)
{
unsigned bin_sizes[] = { 8, 1, 18, 19, 10, 10, 7, 18, 7, 2, 16, 8, 5, 8, 2, 3, 19, 19, 12, 1, 5, 7, 16, 0, 1, 3, 13, 15, 13, 9, 11, 6, 15, 4, 14, 4, 7, 13, 16, 2, 19, 16, 10, 9, 9, 6, 10, 10, 16, 16 };
calc_combinations(bin_sizes);
char* sep = "";
for( unsigned i = 0; i < powers.size(); ++i ) {
if (powers[i]) {
std::cout << sep << i;
sep = " * ";
if (powers[i] > 1)
std::cout << "**" << powers[i];
}
}
std::cout << "\n\n";
}

关于c++ - C++中的组合数(N选R),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9330915/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com