秦九韶算法的思想与解多项式算法时间比较附代码

多项式计算之秦九韶算法

多项式求值与秦九韶算法

一、引言

  多项式函数常常用于描述现实世界的各种规律,而在用计算机计算多项式的值的时候,不同算法的计算时空复杂度通常不一样。如一个n次多项式

  f(x)=a[n]x^n+a[n-1]x^(n-1)+......+a[1]x+a[0],我们的常规计算办法是,直接计算,这样我们的时间复杂度为:O(n^2)

下面我们介绍秦九韶算法:

其核心思想:后面每一次计算都依赖于前面计算的结果,这样以减少重复的计算。

简单引例:

       计算 x^8 直接算将算8次乘法,而这8次都是必要的吗?显然不是,当我们知道x^2的值后,计算x^4只需要用x^2*x^2即可。秦九韶算法正是这样来减少计算量的。

一、推导

  

 

       

  

  a0--->an依次是最高项,到常数项系数

  从而bn就是所求的解

三、算法描述

       由以上推导知,bn就是我们所求的值,要求bn就得逆推到b0,由于b0=a0我们就可以求出b1依次下去就可以求出bn。

数据结构:

       1.数组

                     1.a[]用于保存系数

                     ps:一般做法还需要保存b[],我们这里只是用到前一项,所以一个常数即可

 

c++实现:

 

复制代码
#include <iostream>
using namespace std;
inline double calculate(double x, double* a, int n)
/*
    x:f(x)中的x。a是系数数组
*/
{
    double b = a[0];
    for (int i = 1 ; i <= n; i++)
    {
        b = b * x + a[i];
    }
    return b;
}

int main(int argc, char const argv[])
{
double x = 0;
int n = 0;
cout << “最高项幂:”;
cin >> n;
double
a = new double[n+1];
cout << “\n请输入个项系数(系数为0输入0):”;
for (int i = 0; i <= n; i++)
{
cin >> *(a + i);
}
cout<<"\n要计算的x:";
cin>>x;
double res = calculate(x, a, n);
cout << res << endl;
return 0;
}

复制代码
 MyTest.cpp : 定义控制台应用程序的入口点。
/*
时间测量函调用
*/

#include "stdafx.h"
#include <stdio.h>
#include <time.h>
#include <math.h>
#pragma warning(disable:4996)
#define  MAXN 10
#define MAXK 1e4 
//代表10的7次方
/*f(x)=a0 +a1*x+a2*x*x+a3*x*x*x +...+an*x的N次方  */

clock_t start,stop;
/*clock_t是clock()函数返回的变量的类型*/
double duration;
/*记录被测函数运行的时间,以秒为单位*/

double f1(int n, double a[], double 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){
	int i;
	double p = a[n];
	for (i = n; i > 0; i--){
		p = a[i - 1] + x*p;
	}
	return p;
}

int _tmain(int argc, _TCHAR* argv[])
{
	/*不在测试范围内的准备函数,写在开始之前*/
	int i;
	double a[MAXN];
	for (i = 0; i < MAXN; i++)a[i] = (double)i;
	start = clock();
	for (i = 0; i < MAXK;i++)
		f1(MAXN - 1, a, 1.1);
	stop = clock();
	duration = ((double)(stop - start)) / CLK_TCK / MAXK;
	/*其他不在测试范围外的处理写在后面*/
	printf("ticks1 = %f\n", (double)(stop - start));
	printf("duration1 = %6.2e\n", duration);

	start = clock();
	for (i = 0; i < MAXK;i++)
		f2(MAXN - 1, a, 1.1);
	stop = clock();
	duration = ((double)(stop - start)) / CLK_TCK/MAXK;
	/*其他不在测试范围外的处理写在后面*/
	printf("ticks2 = %f\n", (double)(stop - start));
	printf("duration2 = %6.2e\n", duration);
	/*%6.2e  表示6表示输出长度(包含小数点),2表示输出小数点位数,
	d表示输出为十进制
	e表示用科学计数法表示*/
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值