一元多项式的标准式可以写为:f(x)=。现在给定一个多项式的阶数n,并将全体系数{
}i=0->n,存放在数组a[]里。请写程序计算出这个多项式在给定x处的值。
方法一:根据多项式的标准表达式f(x)=通过循环累计和来实现这个函数。
double f(int n,double a[],double x)
{ /*计算阶数为n,系数为a[0]. . . a[n]的多项式在x点的值*/
int i;
double p=a[0];
for(i=1;i<=n;i++)
p+=a[i]*pow(x,i);
return p;
}
方法二:南宋的数学家秦九昭提出的一种更快的算法,通过不断的提取公因式x来减少乘法的运算次数,把多项式改写为:t
double f(int n,double a[],double x)
{ /*计算阶数为n,系数为a[0]. . . a[n]的多项式在x点的值*/
int i;
double p=a[0];
for(i=n;i>0;i--)
p=a[i-1]+x*p;
return p;
}
头文件time.h中提供了一个clock()函数,这个函数可以捕捉从程序开始运行到clock()被调用时所消耗的时间。这个时间单位是clock tick,即“时钟打点”,在C/C++中定义的数据类型是clock_t。同时还有一个常数CLK_TCK(或是CLOCKS_PER_SEC),给出了机器时钟每秒所走的时钟打点数。
完整程序
#include<stdio.h>
#include<time.h>
#include<math.h>
clock_t start,stop;
double duration;
#define MAXN 10 /* 多项式最大项数,即多项式阶数+1 */
#define MAXK 1e7 /*被测函数重复调用次数*/
double f1(int n,double a[],double x)
{ /*计算阶数为n,系数为a[0]. . . a[n]的多项式在x点的值*/
/*方法一的算法*/
int i;
double p=a[0];
for(i=1;i<=n;i++)
p+=a[i]*pow(x,i);
return p;
}
double f2(int n,double a[],double x)
{ /*计算阶数为n,系数为a[0]. . . a[n]的多项式在x点的值*/
/*方法二的算法*/
int i;
double p=a[0];
for(i=n;i>0;i--)
p=a[i-1]+x*p;
return p;
}
void run(double (*f)(int,double*,double),double a[],int case_n)
{
/*此函数用于测试被测函数(*f)的运行时间,并且根据case_n输出相应的结果*/
/*case_n是输出的函数编号:1代表函数f1;2代表函数f2*/
int i;
start =clock();
for(i=0;i<MAXK;i++) /*重复调用函数以获得充分多的时钟打点数*/
(*f)(MAXN-1,a,1.1);
stop =clock();
duration=((double)(stop-start))/CLK_TCK/MAXK;
printf("ticks%d=%f\n",case_n,(double)(stop-start));
printf("duration%d=%6.2e\n",case_n,duration);
}
int main()
{
int i;
double a[MAXN]; /*存储多项式的系数*/
/*为本题的多项式系数赋值,即a[i]=i */
for(i=0;i<MAXN;i++)
a[i]=(double)i;
run(f1,a,1);
run(f2,a,2);
return 0;
}
编译运行结果

由结果可知,方法二也就是秦九昭的计算速度明显比直接法快了一个量级。