Как эффективно найти коэффициенты полинома от его корней?
Ниже приведены корни n
многочлена, старший коэффициент которого равен 1.
Как эффективно выяснить коэффициенты этого многочлена?
Математически
Я знаю, что если первый коэффициент равен 1, то сумма корней произведения, взятых за время t21 > , будет коэффициентом 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;
}
Я подумал о том, чтобы маркировать числа о том, взяли ли я их в продукт или нет с целью более высоких коэффициентов, но не написали код для него, поскольку он практически бесполезен, если степень многочлена велика.
Ответы
Ответ 1
Вам нужно вычислить произведение линейных коэффициентов
(х-г1) · (х-z 2) ·... · (х-гп)
Это может быть реализовано индуктивно путем многократного умножения многочлена с линейным коэффициентом
(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
На месте это может быть реализовано как loop
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²/2 и такое же количество вычитаний для умножения всех n линейных факторов.
Ответ 2
Прежде всего, в С++ a[n]
есть статический массив, поэтому компилятор должен знать n
во время компиляции, что здесь не так. Таким образом, код "не правильный" в С++. Я знаю, что он будет компилироваться в gcc или других компиляторах, но это противоречит стандарту С++. См. С++ объявляет массив на основе непостоянной переменной? Здесь вам нужен динамический массив, используя команды new
и delete
, или вы можете использовать более безопасный класс std::vector
от STL.
Теперь основная проблема заключается в том, что вам нужны k
вложенные циклы, если вы хотите вычислить коэффициенты k'th
(я принимаю 1, 0-й коэффициент, а не 1-й, только условный). Итак, вам нужно реализовать переменную no. вложенных для циклов в вашем коде. Я отправляю решение вашей проблемы, в котором я использовал метод для реализации переменной no. вложенных для циклов. Надеюсь, это решит вашу проблему.
#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 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
}
Я проверил код, и он работает отлично. Если вы хотите знать, как реализовать переменную no.of вложенных для циклов, просто перейдите в переменную, вложенную для циклов, и посмотрите ответ BugMeNot2013.