趣味编程100例(部分)(6)

2019-03-11 15:23

P(x)=3x6+7x5–3x4+2x3+7x2–7x–15

计算该多项式在指定的x时,P(x)的函数值。 2.问题分析

这是一个数学表达式求值问题,假设我们要求x=2时表达式的值,那么我们可以采用如下的程序代码来实现:

double x=2.0; double P;

P=3*x*x*x*x*x*x+7*x*x*x*x*x-3*x*x*x*x+2*x*x*x+7*x*x-7*x-15; System.out.printf(\

但是,如果重新换一个多项式呢?那么我们就要重新改写代码,重列一个多项式表达式来进行计算。这样显然是比较麻烦的。有没有一个通用的办法来计算多项式的值呢?答案是肯定的,我们可以采用递推的方式。首先可以将上述多项式变形为如下的等价形式: P(x)=(?((an–1x+an–2)x+an–3)x+?+a1)x+a0 通过这个表达式可以看出,只要从里往外一层一层地按照如下的方式递推,便可以计算得到整个一维多项式的值。 Rn–1=an–1

Rk=Rk+1x+ak, k=n–2,?,1,0

通过一层一层地计算后,得到的R0便是多项式P(x)的值。 (1)确定程序框架

有了前面的分析,主要分两步:第一步,如何简单地把多项式表示出来;第二步,给定x的值,把多项式的值计算出来。程序的框架如下:

public class ch2_9 {

public static void main(String[] args) {

//构造多项式 //计算多项式的值

} }

(2)构造多项式

通过前面的问题分析,我们可以知道表达式取决于x的指数及系数,这里我们假设x的指数是递增的,用一个数组存放x的系数,数组的第一项对应x的0次方,第二项对应x的1次方,??。程序的代码如下:

double a[]={-15.0,-7.0,7.0,2.0,-3.0,7.0,3.0};

(3)计算多项式的值

前面的问题分析已经找到了多项式的递推关系,我们可以通过循环的方式实现递推。程序的代码如下:

result=a[n-1];

for (i=n-2; i>=0; i--) //递推算法计算 {

result=result*x+a[i]; }

return result; //返回计算结果

(4)完整程序

现在我们就需要把刚才的程序进行组合,构成我们的完整程序:

import java.text.DecimalFormat; public class ch2_9 {

static double polynomial1D(double a[],int n,double x) {

int i;

double result; result=a[n-1];

for (i=n-2; i>=0; i--) //递推算法计算 {

result=result*x+a[i]; }

return result; //返回计算结果 }

public static void main(String[] args) {

int i;

double a[]={-15.0,-7.0,7.0,2.0,-3.0,7.0,3.0}; //表达式的系数 double[] //x值

x={-2.0,-0.5,1.0,2.0,3.7,4.0};

double result;

DecimalFormat df = new DecimalFormat(\ //数字格式

DecimalFormat df1 = new DecimalFormat(\

System.out.println(\计算P(x)=3x6+7x5-3x4+2x3+7x2-7x-15的值\ for //逐个计算结果

(i=0;

i<6;

i++)

{

result=polynomial1D(a,7,x[i]);

System.out.print(\p(x)=\ (result)+\ }

时,

System.out.print(\ } }

2.11 非线性方程求解(牛顿迭代法) 1.问题描述

非线性方程指方程中包含一个变量的幂次不是1次。例如:y=4x2–3、y=sin(x)–3x+1等等。这种方程多数不存在求根公式,从而求精确根非常困难,甚至不可能,从而寻找方程的近似根就显得特别重要。牛顿迭代法是牛顿在17世纪提出的一种求解方程f(x)=0的方法。 用牛顿迭代法求解如下的非线性方程在x0=2.0附近的方程的解:

2.问题分析

牛顿迭代法的原理:设r是f(x)=0的根,选取x0作为r初始近似值,过点(x0,f(x0))做曲线y=f(x)的切线L,L的方程为y=f(x0)+f '(x0)(x–x0),求出L与x轴交点的横坐标 x1=x0–f(x0)/f '(x0),称x1为r的一次近似值,过点(x1,f(x1))做曲线y=f(x)的切线,并求该切线与x轴的横坐标x2=x1–f(x1)/f '(x1)称x2为r的二次近似值,重复以上过程,得r的近似值序列{Xn},其中Xn1=Xn–f(Xn)/f '(Xn),称为r的n1次近似值。上式称为牛顿迭代公式。

(1)确定程序框架

上面详细分析了牛顿迭代法求解非线性方程的过程,由分析可知,除了非线性方程本身,还要用到非线性方程曲线的切线,所以还要准备好非线性方程的导数方程,然后通过牛顿迭代公式进行迭代,求出方程的近似解。程序的框架如下:

public class ch2_11 {

public static void main(String[] args) {

//构造非线性方程

//构造非线性方程的导数方程 //通过迭代公式求解

} }

(2)构造非线性方程

为简化代码,这里直接写出非线性方程。代码如下:

static

//待求解方程 {

double

func(double

x)

return x*x*x*x-3*x*x*x+1.5*x*x-4.0; }

(3)构造导数方程

为简化代码,这里直接写出非线性方程。代码如下:

static

//导数方程

double

dfunc(double

x)

{

return 4*x*x*x-9*x*x+3*x; }

(4)通过迭代公式求解

从前面的分析可知,其中Xn1=Xn–f(Xn)/f '(Xn)为牛顿迭代公式,通过它很容易写出代码,代码如下:

/**

*x代表初始值

*maxcyc代表迭代次数 *precision代表精确度

*得到结果,返回值为1,否则,返回值为0

*/

static int NewtonMethod(double[] x,int maxcyc,double precision) {

double x0,x1; int i;

x0=x[0]; //参数传递迭代初始值

i=0;

while(i

{

if(dfunc(x0)==0.0) //若通过初值,方法返回值为0

{

System.out.print(\迭代过程中导数为0!\\n\

return 0; }

x1=x0-func(x0)/dfunc(x0); //牛顿迭代计算

if(Math.abs(x1-x0)

//达到预设的结束条件 {

x[0]=x1; //返回结果

return 1; }

else //未达到结束条件

{

x0=x1; //准备下一次迭代

}

i++; //迭代次数累加

}

System.out.print(\迭代次数超过预设值!仍没有达到精度!\\n\ return 0; }

(5)完整程序

现在我们就需要把刚才的程序进行组合,构成我们的完整程序:

public class ch2_11 {

static double func(double x) //待求解方程 {

return x*x*x*x-3*x*x*x+1.5*x*x-4.0; }

static double dfunc(double x) //导数方程

{

return 4*x*x*x-9*x*x+3*x; }

static int NewtonMethod(double[] x,int maxcyc,double precision) {

double x0,x1; int i;

x0=x[0]; //参数传递迭代初始值i=0

while(i

{

if(dfunc(x0)==0.0) //若通过初值,方法返回值为0

{

System.out.print(\迭代过程中导数为0!\\n\


趣味编程100例(部分)(6).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:南昌二中参观学习心得体会

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: