C言語のメモ:多項式の評価の問題

オリジナルリンク: http://c.biancheng.net/c/

多項式のプロフィール

数学で、呼ばれる多項式の複数からなる単項式の代数和(減算場合:そのプラスの反対側に等しい数の保存)。多項式各単項式は、これらの式中の個々の項目の最大数は、多項式の次数で、多項式と呼ばれています。前記多項式の用語、何の文字は定数項と呼ばれていません。

問題のシナリオと実装コード

問題の説明:次の多項式を仮定し、N
ここに画像を挿入説明
iは、用語のnは、多項式(多項式時間の用語の、すなわち、最大数)の程度であり、AI格納されたインデックス係数、xは多項式の引数(double型)であり、ましたそしてn AI及びXの既知の値、多項式f(x)の値
分析:
double型配列の定義[N + 1]、多項式の係数aiを格納し、モジュール、定義された関数Polyf(ダブル[]、最終結果はint nを、二重X)符号の多項式は、以下の4つのソリューションは、異なるアルゴリズムのメリットを検討した定義されています。
これは、多項式f(x)= 1 + 2×想定される ^ 2 + 3X、 多項式に基づいて以下の分析を

/*
假设求多项式f(x)=1+2x+3x^2 
*/
#include <stdio.h>
#include <math.h>
#define N 3
const double x=1.1;//x的实际值 
//数组a存放多项式系数,n为递多项式的次数,x为字母代数 
double Polyf1(double a[],int n,double x);//调用库函数pow() 
double Polyf2(double a[],int n,double x);//用循环语句求x^i 
double Polyf3(double a[],int n,double x);//由迭代x^i=x^(i-1)*x,省略内层循环 
double Polyf4(double a[],int n,double x);//采用秦九韶算法 
int main(void)
{
 double a[N]={1,2,3};
 printf("Polyf1():1+2x+3x^2(x=1.1)=%lf\n",Polyf1(a,2,x));
 printf("Polyf2():1+2x+3x^2(x=1.1)=%lf\n",Polyf2(a,2,x));
 printf("Polyf3():1+2x+3x^2(x=1.1)=%lf\n",Polyf3(a,2,x));
 printf("Polyf4():1+2x+3x^2(x=1.1)=%lf\n",Polyf4(a,2,x));
 return 0;
}
double Polyf1(double a[],int n,double x)
{
 double p=a[0],term;//根据假定要求,多项式第一项不带字母,不需要参与下面的计算 ,term存放x^i的值 
 for(int i=1;i<=n;i++)//n为多项式的次数(次数最高的项的次数,叫做这个多项式的次数。) 
 {
  term=pow(x,i);//求x^i
  p+=a[i]*term;
 }
 return p;
}
double Polyf2(double a[],int n,double x)
{
 double p=a[0],term;
 for(int i=1;i<=n;i++)
 {
  term=1;
  for(int j=1;j<=i;j++)
  {
   term*=x;
  } 
//  term=pow(x,i);
  p+=a[i]*term;
 }
 return p;
}
double Polyf3(double a[],int n,double x)
{
 double p=a[0];
 double term=1;
 for(int i=1;i<=n;i++)
 {
  term*=x;
  p+=a[i]*term;
 }
 return p;
}
double Polyf4(double a[],int n,double x)
{
 double p=a[n];
 for(int i=n-1;i>=0;i--)
 {
  p=p*x+a[i];
 }
 return p;
}

結果:
ここに画像を挿入説明

ソリューションの4種類の分析

方法1:

double Polyf1(double a[],int n,double x)
{
 double p=a[0],term;//根据假定要求,多项式第一项不带字母,不需要参与下面的计算 ,term存放x^i的值 
 for(int i=1;i<=n;i++)//n为多项式的次数(次数最高的项的次数,叫做这个多项式的次数。) 
 {
  term=pow(x,i);//求x^i
  p+=a[i]*term;
 }
 return p;
}

分析方法1:このメソッドは、xのi番目のパワーを見つけ、ヘッダファイルmath.hでダブルPOW(ダブルX、ダブルI)と呼ばれ、そして最終的に係数を乗じた[I]は、各個々の多項式のために得られ、もちろん、第二の方法でのように、あなたはまた、代わりにライブラリ関数を呼び出すのでは独自のループアルゴリズムを書くことができます

方法2:

double Polyf2(double a[],int n,double x)
{
 double p=a[0],term;
 for(int i=1;i<=n;i++)
 {
  term=1;
  for(int j=1;j<=i;j++)
  {
   term*=x;
  } 
  p+=a[i]*term;
 }
 return p;
}

分析方法1及び2:方法1によるライブラリ関数の呼び出しに、この方法の効率は、双方1 + 2 + ... + nは3回の乗算を実行し、すなわち、N = 2の加算、しかしされ、点2よりも僅かに遅いですn個の設定が高すぎる場合は、運転効率が低くなります

方法3:

double Polyf3(double a[],int n,double x)
{
 double p=a[0];
 double term=1;
 for(int i=1;i<=n;i++)
 {
  term*=x;
  p+=a[i]*term;
 }
 return p;
}

方法3と方法2分析:
方法2は(I = 2)、X ^ 2を計算し、最初の計算1 * X、その後のX *(1 * x)は、実際には、とすることができるI = 1 、その値とを保持している場合(i = 2のときの場合)I 1 = 1 * X、Xを乗じ、必要1 * xを計算する際に、直接計算された結果を使用して。游計算X ^ I、利用可能なX ^ i = X ^(iは -1)* X の反復決定。計算用語変数値の、すなわち端改変ポイントを保持するために、その後、インナーループが省略されてもよいです。nが大きい場合、xは^ iが算出される前の反復から生じ得るので、第三の関数の方法は、2回の加算を、すなわち、4回の乗算を2N行わ、N =し、この方法は、一桁より効率を向上させることができます。

方法4:

double Polyf4(double a[],int n,double x)
{
 double p=a[n];
 for(int i=n-1;i>=0;i--)
 {
  p=p*x+a[i];
 }
 return p;
}

分析方法4:
ホーナー法を使用して、ホーナー法は、一価のn倍、n型アルゴリズムの変換後の多項式問題を評価者。
F(X)= 1 + 2X + 3X ^ 2 = 1 +(2 + 3X)X

スピードテスト機能

必要なヘッダファイル:「TIME.H」

必要な機能:時計

プロトタイプ:

clock_t clock( void );

CPUクロックは、関数が(クロックティック)に「プログラムプロセスに」から「プログラムにコールクロック()関数」を返すときの間マダニ

TIME.Hファイルにおいて、CLOCKS_PER_SECはまた、次のように第2タイミングユニットのための多くのクロックを定義する方法を示す定数を定義します。

#define CLOCKS_PER_SEC ((clock_t)1000)  //一秒=1000毫秒

リアルタイムクロック機能を実行するためのプロセスを返しますが、秒よりも実行時間の単位が、CPUのクロック・サイクルは、カウントを実行しています。

だから、時間(秒)を消費しますし、CPUクロックは周波数によって分割され、すなわちCLOCKS_PER_SEC。秒の値を与えるために。

/*
假设求多项式f(x)=1+2x+3x^2 
*/
#include <stdio.h>
#include <math.h>
#include <time.h>
#define N 3
#define K 1e6
clock_t start, end;
double dur;
const double x=1.1;//x的实际值 
double a[N]={1,2,3};
//数组a存放多项式系数,n为递多项式的次数,x为字母代数 
double Polyf1(double a[],int n,double x);//调用库函数pow() 
double Polyf2(double a[],int n,double x);//用循环语句求x^i 
double Polyf3(double a[],int n,double x);//由迭代x^i=x^(i-1)*x,省略内层循环 
double Polyf4(double a[],int n,double x);//采用秦九韶算法 
void Ftick(double (*fp)(double *,int ,double));//测试函数的执行时间 
int main(void)
{
 printf("Polyf1():1+2x+3x^2(x=1.1)=%lf\n",Polyf1(a,2,x));
 printf("Polyf2():1+2x+3x^2(x=1.1)=%lf\n",Polyf2(a,2,x));
 printf("Polyf3():1+2x+3x^2(x=1.1)=%lf\n",Polyf3(a,2,x));
 printf("Polyf4():1+2x+3x^2(x=1.1)=%lf\n",Polyf4(a,2,x));
 Ftick(Polyf1);
 Ftick(Polyf2);
 Ftick(Polyf3);
 Ftick(Polyf4);
 return 0;
}
double Polyf1(double a[],int n,double x)
{
 double p=a[0],term;//根据假定要求,多项式第一项不带字母,不需要参与下面的计算 ,term存放x^i的值 
 for(int i=1;i<=n;i++)//n为多项式的次数(次数最高的项的次数,叫做这个多项式的次数。) 
 {
  term=pow(x,i);//求x^i
  p+=a[i]*term;
 }
 return p;
}
double Polyf2(double a[],int n,double x)
{
 double p=a[0],term;
 for(int i=1;i<=n;i++)
 {
  term=1;
  for(int j=1;j<=i;j++)
  {
   term*=x;
  } 
//  term=pow(x,i);
  p+=a[i]*term;
 }
 return p;
}
double Polyf3(double a[],int n,double x)
{
 double p=a[0];
 double term=1;
 for(int i=1;i<=n;i++)
 {
  term*=x;
  p+=a[i]*term;
 }
 return p;
}
double Polyf4(double a[],int n,double x)
{
 double p=a[n];
 for(int i=n-1;i>=0;i--)
 {
  p=p*x+a[i];
 }
 return p;
}
void Ftick(double (*fp)(double *,int ,double))
{
 double sum;             //fp的返回值
 start=clock();           //记录下面代码开始执行时的时钟打点数
 for(int i = 1;i <= K;i++)     //为了能测出时间,让函数fp执行K次  
     sum = fp(a, N, x);
 end = clock();            //记录上面代码结束时的时钟打点数
 dur=(double)(end - start) / CLK_TCK / K;    //计算函数fp执行一次的时间(秒) 
 printf("f(x) = %f, time=%6.2e\n", sum, dur);   //输出sum及dur  
}

結果は:
ここに画像を挿入説明
あなたは、最後の時間アルゴリズムの実行方法の最短を見つけることができます!

参考:「戦闘を投影するエントリからC言語」-----------王Yiping、編

おすすめ

転載: blog.csdn.net/weixin_42124234/article/details/101630967