使用递归实现霍纳法则

来源:互联网 发布:软件测试大纲 编辑:程序博客网 时间:2024/05/16 01:35

1、介绍

        假设有n+1个实数a0,a1,…,an,和x的序列,要对多项式Pn(x)= anx ^n+a(n-1)x^(n-1)+…+a1x+a0求值,直接方法是对每一项分别求值,并把每一项求的值累加起来,这种方法十分低效,它需要进行n+(n-1)+…+1=n(n+1)/2次乘法运算和n次加法运算。有没有更高效的算法呢?答案是肯定的。通过如下变换我们可以得到一种快得多的算法,即Pn(x)= anx ^n+a(n-1)x^(n-1)+…+a1x+a0=((…(((anx +an-1)x+an-2)x+ an-3)…)x+a1)x+a0,这种求值的安排我们称为霍纳法则。

例如,当x=3时,计算p(x)=2x^4-x^3+3x^2+x-5的值。对于多项式p(x)=2x^4-x^3+3x^2+x-5,我们按霍纳法则进行变换,有:
p(x)=2x^4-x^3+3x^2+x-5
=x(2x^3-x^2+3x+1)-5
=x(x(2x^2-x+3)+1)-5
=x(x(x(2x-1)+3)+1)-5
在实际的操作过程中,为了得到上式,我们没有必要经过上述的特定变换,我们只需要一个该多项式系数的原始列表。我们可以方便地用一个二维表格来帮助我们笔算求出这个多项式的值。该表第一行包含了该多项式的系数(如果存在等于0的系数,也都包含进来),从最高的an到最低的a0。第二行中除了第一个和第二个单元格用来存储x和an外,其它单元格都用来存储中间结果。在作了这样的初始化后,在计算第二行的某一个单元格的值时,用该单元格的前一个单元格乘以x的值再加上该单元格的第一行的系数即可。用这种方式算出的最后一个单元格的值,就是该多项式的值。
系数
a4
a3
a2
a1
a0
系数值
2
-1
3
1
-5
x=3
2
3*2-1=5
3*5+3=18
3*18+1=55
3*55-5=160
所以,P(3)=160。我们拿表格中的单元格和多项式x(x(x(2x-1)+3)+1)-5做比较,我们会发现3*2-1=5是2x-1在x=3时的值,3*5+3=18是x(2x-1)+3在x=3时的值,3*18+1=55是x(x(2x-1)+3)+1在x=3时的值,最后3*55-5=160是x(x(x(2x-1)+3)+1)-5在x=3时的值。

程序实现

#include<stdlib.h>#include<stdio.h>#include<time.h>#define MAX_SIZE 101float horner(float [], int, int, float);int main(){    float coefficient[MAX_SIZE];    /*输入多项式的项数*/    printf("Enter the number of polynomial terms to generate: ");    int n;    scanf("%d", &n);    if(n < 1 || n > MAX_SIZE)    {        fprintf(stderr, "Improper value of n\n");        exit(EXIT_FAILURE);    }    srand((unsigned)time(NULL));    int i;    for(i = 0; i < n; i++)    {        /*随机生成n个系数并存在数组coefficient里*/        coefficient[i] = rand() / (float)(RAND_MAX / 100);        printf("%lf\n", coefficient[i]);    }    /*输入多项式的自变量值*/    printf("\nEnter the value of x: ");    float x0;    scanf("%f", &x0);    /*多项式结果*/    double result = 0;    result = horner(coefficient, n, 0, x0);    printf("\nResult of this polynomial in %f is %f\n", x0, result);    return 0;}float horner(float list[], int n, int i, float x){    if(i == n - 1)        return list[n-1];  /*递归出口*/    else        return horner(list, n, i + 1, x) * x + list[i];  /*递归过程*/}



0 0