1. 程式人生 > >秦九韶演算法的思想與解多項式演算法時間比較附程式碼

秦九韶演算法的思想與解多項式演算法時間比較附程式碼

多項式計算之秦九韶演算法

多項式求值與秦九韶演算法

一、引言

  多項式函式常常用於描述現實世界的各種規律,而在用計算機計算多項式的值的時候,不同演算法的計算時空複雜度通常不一樣。如一個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;
}