多项式系数代码总是提供相同的答案

Multinomial coefficient code always delivers the same answer

我写了下面的代码来求多项式系数,但是总是得到相同的答案,2.122e-314。我已经坐了一段时间了,找不到丢失的东西。我们应该使用递归来做到这一点。我的代码如下:

#include<iostream>
#include<vector>
#include<cerrno>
#include<cstring>

using namespace std;

double binom(int n,int a)
{
double b;
double i;
for (b = 1, i = 1;i <= a; ++i, --n)
        b *= n/i;
return b;
}

double multi(int n, vector<int> a)
{
double b;
int s1 = n;
for ( int s1 = n, b = 1, i = 0; i <= a.size(); ++i, s1 = s1 - a[i-1] )
    b *= binom(s1, a[i]);
return b;
}



int main()
{
int n, k; 
cout << "dimension k: ";
cin >> k;
vector<int> a(k);
cout << "n: ";
cin >> n;
cout << "a[0],...,a[k-1]: ";
for (int i = 0; i < k; ++i)
cin >> a[i];
cout << "Multinomialcoefficient: " << multi(n,a) << endl;
return 0;
}

非常感谢任何帮助。

问题 1

您正在行中执行整数除法

  b *= n/i;

改为

  b *= 1.0*n/i;

问题 2

这是一个阴险的问题。

double b;
int s1 = n;
for ( int s1 = n, b = 1, i = 0; i <= a.size(); ++i, s1 = s1 - a[i-1] )
  b *= binom(s1, a[i]);
return b;

不幸的是,循环中使用 b = 1b 与函数开头声明的 b 不同。由于您使用 int s1 = n, b = 1,,循环中的 b 是一个单独的变量,类型为 int,在循环范围内定义。因此,在函数顶部声明的 b 是未初始化的,这就是你从函数 return 得到的。

提高编译器的警告级别可能会揭示该问题。使用 g++ -Wall,我收到以下警告。

socc.cc:23:11: warning: ‘b’ is used uninitialized in this function [-Wuninitialized]
    return b;

       ^

将该函数更改为:

double multi(int n, vector<int> a)
{
   // Initialize all the variables. Then, the init part of the loop can be empty.
   double b = 1;
   int s1 = n;
   int i = 0;

   for ( ; i <= a.size(); ++i, s1 = s1 - a[i-1] )
      b *= binom(s1, a[i]);
   return b;
}