如何从根中有效地找到多项式的系数?

时间:2015-10-11 17:07:26

标签: c++ algorithm math combinations

给定的是导数系数为1的多项式的n根。 我如何有效地找出这个多项式的系数?

在数学上, 我知道如果第一个系数是1,那么一次取k的产品根的总和将是多项式的k+1-th系数。

我的代码基于这种方法。

换句话说,如何从一次k列表中最佳地找到数字乘积之和。

int main()
{

    int n, sum;
    cin >> n;
    int a[n];
    for (int i=0; i<n; i++) cin >> a[i];
    //for the second coefficient
    sum=0;
    for (int i=0; i<n; i++)
    {
        sum+=a[i];
    }
    cout << sum << endl;
    //for the third coefficient
    sum=0;
    for (int i=0; i<n; i++)
    {
        for (int j=i+1; j<n; j++)
        {
            sum+=a[i]*a[j];
        }
    }
    cout << sum << endl;
}

为了更高系数的目的,我想到了是否将它们带入产品中的数字,但没有为它编写代码,因为如果多项式的程度很大,它实际上是没用的

2 个答案:

答案 0 :(得分:3)

您需要计算线性因子的乘积

  

(X-Z1)·(X-Z2)·...·(X-ZN)

这可以通过将多项式与线性因子

重复相乘来实现
  

(a [0] + a [1]·x + ... + a [m-1]·x ^(m-1))·(x-zm)

     

=(-a [0]·zm)+(a [0] -a [1]·zm)·x + ... +(a [m-2] -a [m-1]·zm)· x ^(m-1)+ a [m-1]·x ^ m

这可以实现为循环

a[m] = a[m-1]
for k = m-1 downto 1
    a[k] = a[k-1] - a[k]*zm
end
a[0] = -a[0]*zm

这为所有n个线性因子的乘法提供了总共n²/ 2次乘法和相同数量的减法。

答案 1 :(得分:1)

首先在C ++中a[n]是一个静态数组,因此编译器需要在编译期间知道n,这不是这里的情况。所以C ++中的代码“不正确”。我知道它将在gcc或其他编译器中编译,但它是针对C ++标准的。请参阅C++ declare an array based on a non-constant variable?这里需要的是动态数组,使用newdelete命令,或者您可以使用STL中更安全的std::vector类。

现在,这里的主要问题是你需要k嵌套循环,如果你想计算k'th系数,(我假设1是第0个系数,而不是第1个,只是约定)。所以,你需要实现变量号。在您的代码中嵌套for循环。我发布了你的问题的解决方案,其中我使用了一个方法来实现变量no。嵌套for循环。希望这能解决你的问题。

#include <iostream>
#include <cmath>
#include <vector>  // include vector class

using namespace std;

double coeff(int,const vector<double>& );  // function declaration to to calculate coefficients

int main()
{

  int N = 5; // no. of roots

  // dynamic vector containing values of roots
  vector<double> Roots(N); 
  for(int i = 0 ; i<N ; ++i)
    Roots[i] = (double)(i+1);  // just an example, you can use std::cin


  int K = 2;  // say you want to know K th coefficient of the polynomial

  double K_th_coeff = coeff(K,Roots); // function call

  cout<<K_th_coeff<<endl; // print the value

  return 0;
}


double coeff(int k,const vector<double>& roots)
{

  int size = roots.size(); // total no. of roots

  int loop_no = k; // total no. of nested loops
  vector<int> loop_counter(loop_no+1); // loop_counter's are the actual iterators through the nested loops
  // like i_1, i_2, i_3 etc., loop_counter[loop_no] is needed to maintain the condition of the loops

  for(int i=0; i<loop_no+1; ++i)
    loop_counter[i]=0;   // initialize all iterators to zero


  vector<int> MAX(loop_no+1); // MAX value for a loop, like  for(int i_1=0; i_1 < MAX[1]; i++)... 
    for(int i=0 ; i<loop_no ; ++i)
      MAX[i] = size - loop_no  + i + 1; // calculated from the algorithm

    MAX[loop_no]=2; // do'es no matter, just != 1

    int  p1=0; // required to maintain the condition of the loops

    double sum(0); // sum of all products

    while(loop_counter[loop_no]==0)
    {
      // variable nested loops starts here

      int counter(0);
      // check that i_1 < i_2 < i_3 ....
      for(int i = 1 ; i < loop_no; ++i)
      {
        if(loop_counter[i-1] < loop_counter[i])
          ++counter;
      }


      if(counter == loop_no - 1) // true if i_1 < i_2 < i_3 ....
      {
        double prod(1);
        for(int i = 0 ; i < loop_no ; ++i)  
          prod *= roots[loop_counter[i]];   // taking products

        sum += prod;  // increament
      }


    // variable nested loops ends here...


    ++loop_counter[0];
    while(loop_counter[p1]==MAX[p1])
      {
        loop_counter[p1]=0;
        loop_counter[++p1]++;
        if(loop_counter[p1]!=MAX[p1])
          p1=0;
      }
    }

    return pow(-1.0,k)*sum;   // DO NOT FORGET THE NEGATIVE SIGN

}

我检查了代码,它运行正常。如果您想知道如何实现嵌套for循环的变量no.of,请访问variable nested for loops并查看BugMeNot2013的答案。