期末考试考点算法相关说明.docx

上传人:b****6 文档编号:7866708 上传时间:2023-01-26 格式:DOCX 页数:14 大小:80.40KB
下载 相关 举报
期末考试考点算法相关说明.docx_第1页
第1页 / 共14页
期末考试考点算法相关说明.docx_第2页
第2页 / 共14页
期末考试考点算法相关说明.docx_第3页
第3页 / 共14页
期末考试考点算法相关说明.docx_第4页
第4页 / 共14页
期末考试考点算法相关说明.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

期末考试考点算法相关说明.docx

《期末考试考点算法相关说明.docx》由会员分享,可在线阅读,更多相关《期末考试考点算法相关说明.docx(14页珍藏版)》请在冰豆网上搜索。

期末考试考点算法相关说明.docx

期末考试考点算法相关说明

以下说明为考试要考到的考点(书上没有的内容)请大家一定要看并记住算法。

说明1clrscr

  函数名:

clrscr

  功能:

清除文本模式窗口清屏的意思就是把之前显示出的文字字符去掉跟cmd里面的清屏的功能是一样的实际上是clearscreen的简写

  用法:

voidclrscr(void);

  程序例:

  #include

  intmain(void)

  {

  inti;

  clrscr();

  for(i=0;i<20;i++)

  cprintf("%d\r\n",i);

  cprintf("\r\nPressanykeytoclearscreen");

  getch();

  clrscr();

  cprintf("Thescreenhasbeencleared!

");

  getch();

  return0;

  }

  

说明2牛顿迭代法

 

编写程序,用牛顿迭代法求方程f(x)=3x3-4x2-5x+13=0的满足精度为10-6的一个近似实根。

  

      分析:

这也是教材习题中要求掌握的一类算法题。

该题涉及到了牛顿迭代法的计算方法:

设一初值x0,然后用牛顿迭代公式x=x0-f(x0)/f'(x0)计算出下一个x,重复不断地用刚计算出的x取代上一个x值,接着再用迭代公式计算新的x,直至两次计算出的x的差额不超过10-6为止。

    正确答案:

-1.548910

 

程序流程分析:

①    输入值x0,即迭代初值;

②    用初值x0代入方程中计算此时的f(x0)及f’(x0),程序中用变量f描述方程的值,用fd描述方程求导之后的值;

③    计算增量d=f/fd;

④    计算下一个x,x=x0-d;

⑤    把新产生的x替换x0,为下一次迭代做好准备;

⑥    若d的绝对值大于1e-5,则重复②③④⑤步。

    源程序代码:

#include

main(){

  floatx,x0,d,f,fd;

  scanf("%f",&x0);

  do{

      f=3*x0*x0*x0-4*x0*x0-5*x0+13;

      fd=9*x0*x0-8*x0-5;

      d=f/fd;

      x=x0-d;

      x0=x;

    }

  while(fabs(d)>1e-5);

  printf("x=%f\n",x);

}

例6.12用牛顿迭代法求方程2x3-4x2+3x-6=0在1.5附近的根

解:

牛顿迭代法又称牛顿切线法。

它采用以下的方法求根:

先任意设定一个与真实的根接近的值x0作为第一次近似根,由x0求出f(x0),过(x0,f(x0))点做f(x)的切线,交x轴于x1,把它作为第二次近似根,再由x1求出f(x1),过(x1,f(x1))点做f(x)的切线,交x轴于x2,求出f(x2);再作切线……如此继续下去,直到足够接近真正的根x*为止。

   f'(x0)=f(x0)/(x1-x0)

因此:

               x1=x0-f(x0)/f'(x0)

这就是牛顿迭代公式。

可以利用它由x0求出x1,然后再由x2求出x3……

设       f(x)=2x3-4x2+3x-6

可以写成以下形式:

f(x)=[(2x-4)x+3]x-6

同样,f'(x)可写成:

f'(x)=6x2-8x+3=(6x-8)x+3

用这种方法表示的表达式,在运算时可节省时间。

例如求f(x)只需要进行3次乘法和3次加法,而原来的表达式要经过多次指数运算、对数运算和乘法、加法运算,花费时间较多。

现在由于计算机的运算速度愈来愈快,这点时间开销是微不足道的,这是以前计算机的运算速度较慢时所提出的问题。

由于过去编写的程序往往采用这种形式,所以我们在此也顺便介绍一下,以便在阅读别人所写的程序时知道其所以然。

程序如下:

(xt6-12.c)

#include

#include

main()

{floatx,x0,f,f1;

  x=1.5;

  do

  {x0=x;

    f=((2*x0-4)*x0+3)*x0-6;

    f1=(6*x0-8)*x0+3;

    x=x0-f/f1;

  }while(fabs(x-x0)>=1e-5);

  printf("Therootofequationis%5.2f\n",x);

}

运行结果:

Therootofequationis2.OO

为了便于循环处理,程序中只设了x0和x,x0代表前一次的近似根,x代表后一次的近似根。

求出一个x后,把它的值赋给x0,然后用它求下一个x0由于第一次执行循环体时,需要对x0赋值,故在开始时应先对x赋一个初值(今为1.5,也可以是接近真实根的其他值)。

说明3二分法

6.13用二分法求下面方程在(-10,10)之间的根。

2x3-4x2+3x-6=0

解:

二分法的思路如下:

先指定一个区间[x1,x2),如果函数f(x)在此区间是单调变化的,则可以根据f(x1)和f(x2)是否同号来确定方程f(x)=0在区间[x1,x2]内是否有一个实根。

若f(x1)和f(x2)不同号,则f(x)=0在区间[x1,x2]内必有一个(且只有一个)实根;如果f(x1)和f(x2)同号,则f(x)在区间[x1,x2]内无实根,要重新改变x1和x2的值。

当确定f(x)在[x1,x2]内有一个实根后,可采取二分法将[x1,x2]一分为二,再判断在哪一个小区间中有实根。

如此不断进行下去,直到小区间足够小为止

具体算法如下:

(1)输入x1和x2的值。

(2)求f(x1)和f(x2)。

(3)如果f(x1)和f(x2)同号说明在[x1,x2]内无实根,返回步骤

(1),重新输入x1和x2的值;若f(x1)和f(x2)不同号,则在[x1,x2]必有一个实根,执行步骤(4)。

(4)求x1和x2的中点:

x0=(x1+x2)/2。

(5)求f(x0)。

(6)判断f(x0)与f(x1)是否同号。

①如果同号,则应在[x0,x2]中寻找根,此时x1已不起作用,用x0代替x1,用f(x0)代替f(x1)。

②如果f(x0)与f(x1)不同号,则说明应在[x1,x0]中寻找根,此时x2已不起作用,用x0代替x2,用f(x0)代替f(x2)。

(7)判断f(x0)的绝对值是否小于某一个指定的值(例如10-5)。

若不小于10-5,则返回步骤(4)重复执行步骤(4)、(5)、(6);否则执行步骤(8)。

(8)输出x0的值,它就是所求出的近似根。

#include

#include

main()

{floatx0,x1,x2,fx0,fx1,fx2;

  do

  {printf("Enterx1&x2:

");

    scanf("%f,%f",&x1,&x2);

    fx1=x1*((2*x1-4)*x1+3)-6;

    fx2=x2*((2*x2-4)*x2+3)-6;

  }while(fx1*fx2>0);

  do

  {x0=(x1+x2)/2;

    fx0=x0*((2*x0-4)*x0+3)-6;

    if((fx0*fx1)<0)

    {x2=x0;

      fx2=fx0;

    }

    else

    {x1=x0;

      fx1=fx0;

    }

  }while(fabs(fx0)>=1e-5);

  printf("x=%6.2f\n",x0);

}

说明4折半查找法

  折半查找法是效率较高的一种查找方法。

假设有已经按照从小到大的顺序排列好的五个整数a[0]~a[4],要查找的数是X,其基本思想是:

  设查找数据的范围下限为l=1,上限为h=5,求中点m=(l+h)/2,用X与中点元素a[m]比较,若X等于a[m],即找到,停止查找;否则,若X大于a[m],替换下限l=m+1,到下半段继续查找;若X小于a[m],换上限h=m-1,到上半段继续查找;如此重复前面的过程直到找到或者l>h为止。

如果l>h,说明没有此数,打印找不到信息,程序结束。

该方法是查找的范围不断缩小一半,所以查找效率较高。

比如{1,3,9,12,32,41,45,62,75,77,82,95,100要找82需要找几次

4次

第一次:

1,3,9,12,32,41,【45】,62,75,77,82,95,100

第二次:

1,3,9,12,32,41,【45】,62,75,【77】,82,95,100

第三次:

1,3,9,12,32,41,【45】,62,75,【77】,82,【95】,100

第四次:

1,3,9,12,32,41,【45】,62,75,【77】,【82】,【95】,100

运用举例

1.//折半查找

2.intBinSearch1(intr[],intn,intk)

3.{

4.intlow=0,high=n;    //设置初始查找区间

5.while(low<=high)            

6.{

7.  intmid=(low+high)/2;//取中间点,比较k与r[mid],        

8.  if(k

9.  high=mid-1;    

10.  else

11.  if(k>r[mid])

12.  low=mid+1;

13.  else

14.  returnmid;  //查找成功

15.}

16.  return0;              //查找失败

说明5选择排序(与书上p1347.3起泡的区别?

原理一次选定数组中的每一个数,记下当前位置并假设它是从当前位置开始后面数中的最小数min=i,从这个数的下一个数开始扫描

直到最后一个数,并记录下最小数的位置min,扫描结束后如果min不等于i,说明假设错误,则交换min与i位置上的数。

用选择法对10个整数排序(从小到大)。

1.程序分析:

所谓选择法就是先将10个数中最小的数与a[0]对换;再将a[1]到a[9]中最小的数与a[1]对换……每比较一轮,找出一个未经排序的数中最小的一个。

共比较9轮。

下面以5个数为例说明选择法的步骤。

a[0]a[1]a[2]a[3]a[4]

36194未排序时的情况

16394将5个数中最小的数1与a[0]对换

13694将余下的4个数中最小的数3与a[1]对换

13496将余下的3个数中最小的数4与a[2]对换

13469将余下的2个数中最小的数6与a[3]对换,至此完成排序

2.程序流程图:

3.程序N-S图:

4.程序源代码:

voidsort(intarray[],intn)

inti,j,k,t;

for(i=0;i

   {k=i;

    for(j=i+1;j

  if(array[j]

    t=array[k];array[k]=array[i];array[i]=t;

main()

inta[10],i;

printf("enterthearray:

\n");

 for(i=0;i<10;i++)

  scanf("%d",&a[i]);

 sort(a,10);

 printf("thesortedarray:

\n");

 for(i=0;i<10;i++)

  printf("%d",a[i]);

 printf("\n");

 }

5.程序运行结果:

enterthearray:

36194

thesortedarray:

13469

以下是一些历年来必考的重点内容,也请记住p1296.1,6.6,6.11三道题的解法及原理,具体原理例题如下

辗转相除法

  辗转相除法,又名欧几里德算法(Euclideanalgorithm)乃求两个正整数之最大公因子的算法。

它是已知最古老的算法,其可追溯至3000年前。

它首次出现于欧几里德的《几何原本》(第VII卷,命题i和ii)中,而在中国则可以追溯至东汉出现的《九章算术》。

它并不需要把二数作质因子分解。

  证明:

  设两数为a、b(b<a),求它们最大公约数(a、b)的步骤如下:

用b除a,得a=bq......r1(0≤r)。

若r1=0,则(a,b)=b;若r1≠0,则再用r1除b,得b=r1q......r2(0≤r2).若r2=0,则(a,b)=r1,若r2≠0,则继续用r2除r1,……如此下去,直到能整除为止。

其最后一个非零余数即为(a,b)。

  [编辑]算法

  辗转相除法是利用以下性质来确定两个正整数a和b的最大公因子的:

  1.若r是a÷b的余数,则

  gcd(a,b)=gcd(b,r)

  2.a和其倍数之最大公因子为a。

  另一种写法是:

  1.a÷b,令r为所得余数(0≤r<b)

  若r=0,算法结束;b即为答案。

  2.互换:

置a←b,b←r,并返回第一步。

P1296.1输入两个正整数m和n,求其最大公约数和最小公倍数.

<1>用辗转相除法求最大公约数

算法描述:

m对n求余为a,若a不等于0

则m<-n,n<-a,继续求余

否则n为最大公约数

<2>最小公倍数=两个数的积/最大公约数

#include

intmain()

{

intm,n;

intm_cup,n_cup,res;/*被除数,除数,余数*/

printf("Entertwointeger:

\n");

scanf("%d%d",&m,&n);

if(m>0&&n>0)

{

m_cup=m;

n_cup=n;

res=m_cup%n_cup;

while(res!

=0)

{

m_cup=n_cup;

n_cup=res;

res=m_cup%n_cup;

}

printf("Greatestcommondivisor:

%d\n",n_cup);

printf("Leasecommonmultiple:

%d\n",m*n/n_cup);

}

elseprintf("Error!

\n");

return0;

}

水仙花数P1296.6  找出所有的水仙花数.水仙花数是一个3位数,其各位数字立方和等于该数本身

#include

voidmain()

{

 inti,j,k,n;

 printf("水仙花数是:

");

 for(n=100;n<1000;n++)

 {

  i=n/100;

  j=n/10-i*10;

  k=n%10;

  if(n==i*i*i+j*j*j+k*k*k)

   printf("%4d",n);

 }

 printf("\n");

}

迭代法的相关概念及典型例题

  迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程,跟迭代法相对应的是直接法(或者称为一次解法),即一次性解决问题。

迭代法又分为精确迭代和近似迭代。

“二分法”和“牛顿迭代法”属于近似迭代法。

  迭代算法是用计算机解决问题的一种基本方法。

它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。

  利用迭代算法解决问题,需要做好以下三个方面的工作:

  一、确定迭代变量。

在可以用迭代算法解决的问题中,至少存在一个直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量。

  二、建立迭代关系式。

所谓迭代关系式,指如何从变量的前一个值推出其下一个值的公式(或关系)。

迭代关系式的建立是解决迭代问题的关键,通常可以使用递推或倒推的方法来完成。

三、对迭代过程进行控制。

在什么时候结束迭代过程?

这是编写迭代程序必须考虑的问题。

不能让迭代过程无休止地重复执行下去。

迭代过程的控制通常可分为两种情况:

一种是所需的迭代次数是个确定的值,可以计算出来;另一种是所需的迭代次数无法确定。

对于前一种情况,可以构建一个固定次数的循环来实现对迭代过程的控制;对于后一种情况,需要进一步分析出用来结束迭代过程的条件。

求平方根的迭代公式:

x1=1/2*(x0+a/x0)。

  算法:

1.先自定一个初值x0,作为a的平方根值,在我们的程序中取a/2作为a的初值;利用迭代公式求出一个x1。

此值与真正的a的平方根值相比,误差很大。

  2.把新求得的x1代入x0中,准备用此新的x0再去求出一个新的x1.

  3.利用迭代公式再求出一个新的x1的值,也就是用新的x0又求出一个新的平方根值x1,此值将更趋近于真正的平方根值。

  4.比较前后两次求得的平方根值x0和x1,如果它们的差值小于我们指定的值,即达到我们要求的精度,则认为x1就是a的平方根值,去执行步骤5;否则执行步骤2,即循环进行迭代。

  迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。

设方程为f(x)=0,用某种数学方法导出等价的形式x=g(x),然后按以下步骤执行:

  

(1)选一个方程的近似根,赋给变量x0;

  

(2)将x0的值保存于变量x1,然后计算g(x1),并将结果存于变量x0;

  (3)当x0与x1的差的绝对值还小于指定的精度要求时,重复步骤

(2)的计算。

  若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的x0就认为是方程的根。

上述算法用C程序的形式表示为:

  【算法】迭代法求方程的根

  {x0=初始近似根;

  do{

  x1=x0;

  x0=g(x1);/*按特定的方程计算新的近似根*/

  }while(fabs(x0-x1)>Epsilon);

  printf(“方程的近似根是%f\n”,x0);

  }

  迭代算法也常用于求方程组的根,令

  X=(x0,x1,…,xn-1)

  设方程组为:

  xi=gi(X)(I=0,1,…,n-1)

  则求方程组根的迭代算法可描述如下:

  【算法】迭代法求方程组的根

  {for(i=0;i

  x=初始近似根;

  do{

  for(i=0;i

  y=x;

  for(i=0;i

  x=gi(X);

  for(delta=0.0,i=0;i

  if(fabs(y-x)>delta)delta=fabs(y-x);

  }while(delta>Epsilon);

  for(i=0;i

  printf(“变量x[%d]的近似根是%f”,I,x);

  printf(“\n”);

  }

  具体使用迭代法求根时应注意以下两种可能发生的情况:

  

(1)如果方程无解,算法求出的近似根序列就不会收敛,迭代过程会变成死循环,因此在使用迭代算法前应先考察方程是否有解,并在程序中对迭代的次数给予限制;

  

(2)方程虽然有解,但迭代公式选择不当,或迭代的初始近似根选择不合理,也会导致迭代失败。

P1296.11用迭代法求某数a的平方根。

已知求平方根的迭代公式为:

xn+1=(xn+a/xn)/2

要求前后两次求出的差的绝对值小于10-5。

算法如下:

①设定一个x的初值x0;(在如下程序中取x0=a/2,通过迭代公式求出x1,可以肯定与真正的平方根相比,误差很大。

②用上述公式求出x的下一个值x1;

③如此继续下去,直到前后两次求出的x值(xn+1和xn)满足以下关系:

|xn+1-xn|<10-5.

#include

#include

int  main()

{

   floata;     

   floatx0,x1;

   printf("Inputapositivenumber:

\n");

   scanf("%f",&a);

   x0=a/2;  

   x1=(x0+a/x0)/2;

   while(fabs(x1-x0)>=1e-5)

   {

       x0=x1;

       x1=(x0+a/x0)/2;

   }

   printf("Thesquarerootof%5.2fis%8.5f\n",a,x1);

   return0;

}

运行结果:

=====================================

Inputapositivenumber:

2↙

Thesquarerootof 2.00is 1.41421

以上内容大家必须在理解的基础上记忆,如实在无法理解请将关键思想(算法步骤)强记,对考试定有帮助。

祝大家考出好成绩

谢谢大家一学期来的支持预祝新春快乐

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1