多项式系数代码总是提供相同的答案
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 = 1
的 b
与函数开头声明的 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;
}
我写了下面的代码来求多项式系数,但是总是得到相同的答案,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 = 1
的 b
与函数开头声明的 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;
}