第8章-程序VB循环结构程序设计课件_第1页
第8章-程序VB循环结构程序设计课件_第2页
第8章-程序VB循环结构程序设计课件_第3页
第8章-程序VB循环结构程序设计课件_第4页
第8章-程序VB循环结构程序设计课件_第5页
已阅读5页,还剩92页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章循环结构程序设计第8章循环结构程序设计1学习重点

For…Next语句、Do…Loop语句、While…Wend语句、GoTo语句。循环语句的嵌套使用。掌握常用的循环结构算法。学习重点For…Next语句、Do…Loop语句、Whil2本章内容8.1For…Next语句8.2Do…Loop语句8.3While…Wend语句8.4GoTo语句8.5循环嵌套8.6常用算法及实例本章小结本章内容8.1For…Next语句3引言循环:重复进行某些相同或相近的操作

循环结构语句:

程序自动重复执行代码段。

VisualBasic中的循环结构语句:

For…Next语句

Do…Loop语句

While…Wend语句引言循环:重复进行某些相同或相近的操作48.1For…Next语句

For…Next语句(也称步长循环语句),常用于在循环开始前能确定循环执行次数的情况。For…Next语句格式如下:

For循环变量=初值To终值[Step步长]

[语句块]

[ExitFor]

[语句块]

Next循环变量功能:以指定次数来重复执行一组语句。

8.1For…Next语句For…Next语句(也称步5示例代码:

DimiAsInteger

Fori=1To10Step1

Printi;

Nexti执行以上代码将在窗体上输出结果如下:

12345678910For循环变量=初值To终值[Step步长]

[语句块]

[ExitFor]

[语句块]

Next循环变量示例代码:

DimiAsInteger

Fori=6关于循环的几个概念:循环变量——又称为“循环控制变量”、“控制变量”或“循环计数器”,是用做循环计数器的数值变量。这个变量必须为数值型变量,不能是逻辑型数据或数组元素。

循环体——被重复执行的代码段。循环次数——循环体被重复执行的次数。循环次数必须是有限的,否则称程序陷入“死循环”关于循环的几个概念:7DimiAsInteger

Fori=1To10Step1

Printi;

Nexti说明:上述代码中整型变量i是循环变量。

初值、终值和步长也必须是数值表达式。步长可以是正数或负数,仅当步长为1时,“Step步长”可以省略。当步长是正数或零时,要求循环变量小于或等于终值;当步长是负数时,要求循环变量大于或等于终值。若不符合以上情况时,不能进入循环执行语句块。在上述代码中循环变量i的初值是1,终值是10,步长是1。

DimiAsInteger

Fori=1To108DimiAsInteger

Fori=1To10Step1

Printi;

NextiFor和Next中间的语句段称为循环体。在上述代码中循环体仅有一条语句构成。可以在循环体中任何位置放置任意个ExitFor语句,随时退出循环。ExitFor经常在条件判断之后使用,如If…Then语句之后,并将控制权转移到紧接在Next之后的语句。如将上述代码改为

DimiAsInteger

Fori=1To10Step1

Printi;

Ifi>5ThenExitFor

Nexti

程序的输出就变为12345。

DimiAsInteger

Fori=1To1098.1For…Next语句For…Next语句执行过程:①首先计算初值、终值和步长表达式的值,并将它们都转换成与循环变量相同的类型。②将计算好的初值表达式的值赋给循环变量,作为循环变量的初值,注意循环变量仅被赋初值一次。③进行判别:判断循环变量的值是否超过终值,即当步长>0(步长为正数)时,判别循环变量>终值否;当步长<0(步长为负数)时,判别循环变量<终值否,如果未超过,则进入执行循环体;如果超过了,则正常退出结束循环,去执行Next语句的下一语句。④

执行Next语句,使循环变量增加一个步长,即执行循环变量=循环变量+步长;返回步骤③继续进行判别。

图8-1For…Next语句程序流程图

8.1For…Next语句For…Next语句执10DimiAsInteger

Fori=1To10Step1

Printi;

Nexti上述代码中循环变量的初值是1,以后每次执行到For语句时判断i<=10是否成立,成立则执行循环体中的语句,即输出变量i当前的值,否则结束循环,每次执行到Next语句时将循环变量i的值自增1。因此,循环变量i的值从1一直变化到10,并将这些值输出。最后一次执行过Next语句后,变量i的值是11,因为超出终值而结束循环。一般地,若循环体中不出现类似于ExitFor和ExitSub之类的强制跳转语句时,结束For循环时循环变量的值肯定超过了终值。

DimiAsInteger

Fori=1To10118.1For…Next语句循环次数的一般计算公式如下:

循环次数=Int(Abs(终值-初值)/步长)+1注意,若循环变量在循环体内被重新赋值,则会影响和改变循环次数。示例代码如下:

Fori=1to100

i=i+1

Nexti以上循环体中i的值自增了1,而语句Nexti还将使i的值增加1,因此在进入后一次循环时i的值比前一次进入循环时共增加了2,因此循环也就执行了50次。8.1For…Next语句循环次数的一般计算公式如下:

128.1For…Next语句注意:初值、终值和步长值仅在步骤①中计算,在循环体内对这三个值所涉及的变量进行值的更改,都不会改变循环进行中的初值、终值和步长值,当然也不会影响循环次数。

以下3段代码中的循环执行次数均为

Int((20-1)/2)+1=10次。

代码1:

代码2:

代码3:

ForI=1to20step2 c=c+1NextI

c=20ForI=1tocstep2 c=c+1NextId=2ForI=1to20stepd d=d+1NextI执行后c的值是10执行后c的值是30执行后d的值是128.1For…Next语句注意:初值、终值和步长值仅在步138.1For…Next语句格式中Next后面的循环变量有时被省略,但不推荐这样使用。如果省略,则由系统自己去识别该Next对应的循环变量,并对它进行相应的步长运算。如以下代码也是正确的。

Fori=1To10Step1

Printi;

Next '省略循环变量8.1For…Next语句格式中Next后面的循环变量有14For…Next举例例8-1

求1+2+3+…+100

PrivateSubCommand1_Click()

DimiAsInteger,sumAsInteger

sum=0 ‘变量sum清零

Fori=1To100

sum=sum+i ’累加

NextI

Printsum

EndSub本题输出结果是5050。思考:如何实现n!=1×2×3×…×n?

For…Next举例例8-1求1+2+3+…+100

15For…Next举例例8-2

输出1~200间所有能被3整除的数,要求每行输出10个数。

第1种方法实现如下:PrivateSubCommand1_Click()DimxAsInteger,nAsIntegerForx=1To200IfxMod3=0ThenPrintx;n=n+1IfnMod10=0ThenPrintEndIfNextxPrintEndSub第2种方法实现如下:PrivateSubCommand2_Click()DimxAsInteger,nAsIntegerForx=3To200Step3Printx;n=n+1IfnMod10=0ThenPrintNextxPrintEndSubFor…Next举例例8-2输出1~200间所有能被3整168.2Do…Loop语句

8.2.1当型循环

8.2.2直到型循环

8.2Do…Loop语句8.2.1当型循环178.2.1当型循环当型Do…Loop语句格式如下:

Do[While循环条件]

[语句块]

[ExitDo]

[语句块]

Loop

Do

[语句块]

[ExitDo]

[语句块]

Loop

[While循环条件]功能:当循环条件为True时,重复执行语句块中的命令。8.2.1当型循环当型Do…Loop语句格式如下:

D188.2.1当型循环如用以下代码也可以在窗体上输出12345678910。

DimiAsInteger

i=1

DoWhilei<=10

Printi;

i=i+1

Loop

DimiAsInteger

i=1

Do

Printi;

i=i+1

LoopWhilei<=108.2.1当型循环如用以下代码也可以在窗体上输出12198.2.1当型循环说明:(1)“循环条件”通常是一个关系或逻辑表达式,其值为True或False。(2)Do和Loop间的语句块是循环体,当循环条件为True时,重复执行循环体,当循环条件为False时,结束循环,转入Loop后的语句执行。8.2.1当型循环说明:208.2.1当型循环说明:(3)两种格式的当型Do…Loop语句对应的流程图如图8-2所示,两者的区别是:图8-2(a)表示每一次进入循环,总是先判断循环条件是否为“True”,然后再决定是否进入执行循环体语句;而图8-2(b)先执行一次循环体语句,再判别循环条件是否为真“True”,以决定是否再次执行循环体。即图8-2(a)的循环形式有可能一次也没执行循环体语句,而图8-2(b)中不管循环条件是否为真,至少执行一次循环体语句。但一旦图8-2(a)进入循环,其循环次数和对应的图8-2(b)循环次数相等。(a)DoWhile…Loop结构流程图

(b)Do…LoopWhile结构流程图

8.2.1当型循环说明:(a)DoWhile…Loop218.2.1当型循环说明:(4)Do…Loop语句中可以在任何位置放置任意个数的ExitDo语句,随时跳出Do…Loop循环。ExitDo只能用于Do…Loop语句中,通常用于条件判断之后。如以下代码中没有设置循环条件,而采用在循环体中有条件的跳出来设置循环终止条件。

DimiAsInteger

i=1

Do

Printi;

i=i+1

Ifi>10ThenExitDo

Loop8.2.1当型循环说明:228.2.1当型循环说明:(5)为了使循环语句在有限的时间内执行完毕,在循环体中至少要有一条语句使得循环条件趋向于假“False”或用ExitDo语句终止循环,否则程序将无休止的执行循环体,直至耗尽系统资源,我们称这种现象为“死循环”。

提示

当程序进入“死循环”或长时间执行某过程时,用户可以使用Ctrl+Break键强行中断程序的运行,将程序从运行状态改为设计状态,并释放程序运行中的临时资源。

8.2.1当型循环说明:238.2.1当型循环说明:(6)可以将For…Next语句改写成Do…Loop语句,但仅有已知循环次数的Do…Loop语句才可以改写成For…Next语句。在For…Next语句中,格式中包含了对循环变量的赋初值、设置循环进行的条件及循环变量按步长变化等操作,这些在Do…Loop语句中都需要编程人员一一考虑并用语句设置。

8.2.1当型循环说明:248.2.1当型循环例8-3

验证谷角猜想。对于任意一个自然数n,若n为偶数,则将其除以2;若n为奇数,则将其乘以3,然后再加1。如此经过有限次运算后,总可以得到自然数1。

分析:由于不能确定要多少步才能结束运算,因此本题中采用当型Do…Loop循环语句实现。使用变量n存放该正整数,每次重新计算出的新值仍然存放在n中。当n未达到1时继续执行运算,当n等于1时结束循环。

8.2.1当型循环例8-3验证谷角猜想。对于任意一个25例8-3代码:PrivateSubCommand1_Click()DimnAsIntegerCls '清屏n=Val(InputBox("请输入一个正整数"))Printn;Ifn>0ThenDoWhilen<>1IfnMod2=1Thenn=n*3+1Elsen=n/2EndIfPrint"->";n;LoopEndIfEndSub例8-3代码:PrivateSubCommand1_Cl268.2.2直到型循环

直到型Do…Loop语句格式如下:

Do[Until循环条件]

[语句块]

[ExitDo]

[语句块]

Loop

Do

[语句块]

[ExitDo]

[语句块]

Loop

[Until循环条件]功能:当循环条件为False时,重复执行语句块中的命令;当循环条件为True时,结束循环。8.2.2直到型循环直到型Do…Loop语句格式如下278.2.2直到型循环如用以下代码也可以在窗体上输出12345678910。

DimiAsInteger

i=1

DoUntili>10

Printi;

i=i+1

Loop

DimiAsInteger

i=1

Do

Printi;

i=i+1

LoopUntili>108.2.2直到型循环如用以下代码也可以在窗体上输出1288.2.2直到型循环说明:(1)直到型Do…Loop语句也有两种形式。(a)DoUntil…Loop结构流程图

(b)Do…LoopUntil结构流程图

8.2.2直到型循环说明:(a)DoUntil…Lo298.2.2直到型循环说明:(2)直到型Do…Loop语句格式中的组成和当型Do…Loop语句格式基本一致,两者的区别是两者的循环条件正好相反。

大部分当型Do…Loop语句都可以改写成直到型Do…Loop语句。如将例8-3中的DoWhilen<>1改成DoUntiln=1,程序功能完全一致。

8.2.2直到型循环说明:30例8-4例8-4

随机产生n个随机整数,并求它们的平均值,n由用户输入。

分析:用户输入信息的有效性过滤:使用整型变量n接收用户输入的数据,可以过滤掉非数值字符串

采用Fix函数进行取整可以将用户输入的实数类型数据转换为整数

使用一个Do…Loop循环对负数进行过滤,并由用户选择是否继续输入

例8-4例8-4随机产生n个随机整数,并求它们的平均值,31例8-4PrivateSubForm_Click()DimnAsInteger,xAsInteger,iAsInteger,sumAsIntegern=Fix(Val(InputBox("请输入数据个数"))) '舍去取整DoUntiln>0IfMsgBox("输入错误,需要重新输入吗?",vbYesNo)=vbYesThenn=Fix(Val(InputBox("请输入数据个数")))ElseExitSub '结束本事件过程EndIfLoop实现数据n的输入例8-4PrivateSubForm_Click()实现32例8-4sum=0 '累加器sum清零Fori=1Tonx=Int(Rnd*100)sum=sum+xPrintx;IfiMod10=0ThenPrint '每行输出5个数据NextiPrintPrintn;"个数的平均值=";sum/nEndSub功能实现——求n个数的平均值

例8-4sum=0338.3While…Wend语句

语句格式:While循环条件循环体Wend在窗体上输出12345678910。DimiAsIntegeri=1Whilei<=10Printi;i=i+1Wend这种结构使用完全类似于当型Do…Loop循环语句的格式1

8.3While…Wend语句语句格式:在窗体上输出1348.4GoTo语句

语句格式如下:GoTo标签其中标签无需定义,是在一行语句的开头用冒号和语句隔开的标识符。

说明:(1)GoTo语句是一个无条件转支语句,通常和分支语句配合使用。

PrivateSubForm_Click()DimxAsIntegerx=Val(InputBox("请输入一个正整数"))Ifx<0ThenGoToL1PrintxL1:EndSub

程序功能:

只输出用户输入的正整数

8.4GoTo语句语句格式如下:PrivateSub358.4GoTo语句(2)使用GoTo语句可以构造出一个具有循环功能的结构。在窗体上以紧凑格式输出数值1~10。

DimiAsInteger

i=1

A:Printi;

i=i+1

Ifi<=10ThenGoToA执行以上程序段后i的值是11。8.4GoTo语句(2)使用GoTo语句可以构造出一个具368.4GoTo语句(3)在循环语句中使用GoTo语句,既可以从循环内部跳转到循环外部语句,也可以从循环外部语句跳转到循环内部语句,但要注意由此产生的循环执行过程的变化。

如:

DimiAsInteger

Fori=1To10

B:Printi;

Nexti

Ifi<=11ThenGoToB以紧凑格式输出数值1~11不恰当的GoTo语句将使程序陷入死循环C:Fori=1To9Print"*"Ifi>5ThenGoToCNexti

8.4GoTo语句(3)在循环语句中使用GoTo语句,既378.4GoTo语句(4)结构化程序设计中并不建议使用GoTo语句来控制程序流程,因为它会使程序流程复杂化。

8.4GoTo语句(4)结构化程序设计中并不建议使用Go388.5循

循环嵌套是指在某个循环的循环体中又包含着另一个完整的循环。8.5循环嵌套循环嵌套是指在某个循环的循环体中又398.5循

套说明:

(1)嵌套的层数没有具体限制,但内层的小循环一定要完整地被包含在外层的大循环之内,而不得相互交叉。

以下两种结构中语句之间存在着交叉,是不正确的:

Do...

For......LoopNext...Fori=1To10...Forj=1To10...Nexti...Nextj8.5循环嵌套说明:

(1)嵌套的层数没有具体限制408.5循

套(2)对有循环控制变量的循环进行嵌套时,要注意循环嵌套后对改变循环变量的值是否影响循环次数等。(3)循环嵌套的层次数不能太多,要考虑实际语句的执行次数。一般的,在内层循环体中的语句执行次数=每次内层循环次数×外层循环次数。(4)若有多层For…Next语句嵌套,且各自的Next语句在连续位置上,则可将多条Next语句合并成一条语句,格式是Next内层循环变量,外层循环变量……

以下代码是正确的。Fora=1to5 Forb=1to5 Forc=1to5 …Nextc,b,a'等价于三条语句Nextc:Nextb:Nexta8.5循环嵌套(2)对有循环控制变量的循环进行嵌套41程序举例例8-5如有以下程序代码:

i=1

DoWhilei<=10

s=1

Fori=1Toi

s=s*i

Nexti

Printi;"!=";s

i=i+1

Loop程序的本意是要分别输出1~10的阶乘,但程序的输出如图所示,除了输出的行数不符外,我们还发现每行上求的值也不符合。

程序举例例8-5如有以下程序代码:

i=1

42例8-5分析其原因发现,内层循环对变量i的变化影响了外层循环的正常执行。解决的方法是每一个循环使用一个唯一的循环控制变量(不同名)。修改代码:

DimiAsInteger,sAsDoublei=1DoWhilei<=10s=1Forj=1Tois=s*jNextjPrinti;"!=";si=i+1Loop例8-5分析其原因发现,内层循环对变量i的变化影响了外层循环43程序举例例8-6

输出九九乘法表

PrivateSubForm_Activate()DimiAsInteger,jAsIntegerFori=1To9Forj=1To9Picture1.PrintTab(10*(j-1));CStr(i);"*";CStr(j);"=";CStr(i*j);NextjPicture1.PrintNextiEndSub思考:如何输出只有下三角区域的九九乘法表?

程序举例例8-6输出九九乘法表PrivateSub448.6常用算法及实例

8.6.1累加(乘)8.6.2求最值8.6.3穷举法8.6.4递推法(迭代法)8.6.5字符串遍历8.6.6有限状态自动机8.6.7进制转换8.6.8图形字符的打印

8.6常用算法及实例8.6.1累加(乘)458.6.1累加(乘)累加(乘)是指在某个值的基础上一次又一次的加上(乘以)一些数。累加(乘)的结果是运算最终的目标,通常只需使用一个变量来存放在各次运算结果,称这样的变量为累加(乘)器。

1.累加2.累乘

8.6.1累加(乘)累加(乘)是指在某个值的基础上一次又461.累加算法描述如下。步骤1:给累加器变量sum赋初值为0,给计数器i赋初值为0。步骤2:计数器加1,即i+1i。步骤3:计算ai。步骤4:ai+sumsum。步骤5:ai是否是最后一项,若是则转步骤6,否则转步骤2。步骤6:输出累加器变量sum的值。

1.累加算法描述如下。471.累加程序模式:(1)若已知i的取值范围是1~k,则用以下语句组合来计算累加和sum。

sum=0

Fori=1tok

sum=sum+ai

Nexti(2)若已知最后一项的取值要求,则用以下语句组合来计算累加和sum。

sum=0:i=1

DoWhileai满足条件‘或DoUntilai不满足条

sum=sum+ai

i=i+1

Loop1.累加程序模式:482.累乘算法描述与累加相似,主要区别在于:

(1)累乘器的初值赋为1

(2)使用sum=sum*ai进行累乘运算。同样的,也可以总结出类似的累乘程序模式加以运用。

2.累乘算法描述与累加相似,主要区别在于:

(1)累乘器的49程序举例例8-7

正弦函数可表示为

使用该公式求sinx的近似解,直到累加项的绝对值小于10-6为止。

分析:这是一个累加问题,使用累加模式实现。其中,通项中分子是个阶乘,需要使用累乘模式实现。

程序举例例8-7正弦函数可表示为

使用该公式求sin50例8-7PrivateSubCmdcul_Click()DimxAsSingle,iAsInteger,jAsIntegerDimsumAsSingle,tAsSingle,fAsSinglex=Val(txtX.Text)i=1Dof=1 '求2i-1的阶乘,放入变量f中Forj=1To2*i-1f=f*jNextjt=(-1)^(i-1)*x^(2*i-1)/f '通项t的计算sum=sum+t '累加i=i+1LoopUntilAbs(t)<10^(-6)txtResult.Text=Format(sum,"0.00000")EndSub多项式法

例8-7PrivateSubCmdcul_Click()518.6.2求最值

最值问题一般表现为求n个数中的最大(小)值。算法描述如下。

步骤1:给存放最大(小)值的变量赋初值。

步骤2:取n个数中的一个数和最大(小)值变量比较,若大于最大值变量(小于最小值变量),则将该数赋值给最大(小)值变量。

步骤3:重复步骤2,直至所有数都比较完成。

8.6.2求最值最值问题一般表现为求n个数中的最大(小52程序举例例8-8

使用随机函数生成30个学生的数学成绩,并求其中的最高分。

分析:百分制分数的范围是0~100,设最大值变量max的初值为0,以保证在第1次数据比较时就能使max等于第一个数。

程序举例例8-8使用随机函数生成30个学生的数学成绩,并53例8-8PrivateSubForm_Click()DimgradeAsInteger,iAsInteger,maxAsIntegerPrint"30个学生的数学成绩是:"max=0 '设置最大值为一个相对小的数Fori=1To30grad=Int(101*Rnd) '随机生成百分制成绩Printgrad;IfiMod10=0ThenPrintIfgrad>maxThenmax=gradNextiPrint"最高分是";maxEndSub例8-8PrivateSubForm_Click()54例8-8这种对max赋初值的方法在有些场合并不适用,为了能确保max中只存放真实数据中的一个,我们可以将第1个数据作为初值赋给max,然后从第2个数开始和max比较。改进:PrivateSubForm_Click()DimgradeAsInteger,iAsInteger,maxAsIntegerPrint"30个学生的数学成绩是:"grad=Int(101*Rnd) '生成第一个成绩Printgrad;max=grad '设置最大值为第1个数Fori=2To30 '从第2个数开始比较grad=Int(101*Rnd)Printgrad;IfiMod10=0ThenPrintIfgrad>maxThenmax=gradNextiPrint"最高分是";maxEndSub例8-8这种对max赋初值的方法在有些场合并不适用,为了能确558.6.3穷举法

穷举法主要通过将可能出现解的范围中所有的数一一进行判断。搜索范围的确定是穷举法的关键,一旦确定了范围,使用常规的循环语句即可解决问题。1.组合问题

2.素数问题

8.6.3穷举法穷举法主要通过将可能出现解的范围中所有561.组合问题

组合问题一般体现在要求符合条件的所有组合情况,此类问题的关键是要按一定的顺序进行穷举,避免遗漏。

例8-9

求由数字0、1、2、3、4组成的所有无重复数字的3位正整数。

分析:分别对3位数的3个位数字进行穷举,其中百位数字不能为0。使用三重循环来实现,

1.组合问题组合问题一般体现在要求符合条件的所有组合情况,57例8-9PrivateSubForm_Click()DimaAsInteger,bAsInteger,cAsInteger,nAsIntegerFora=1To4Forb=0To4Forc=0To4Ifa<>bAndb<>cAnda<>cThenPrinta*100+b*10+c;n=n+1IfnMod5=0ThenPrintEndIfNextcNextbNextaEndSub例8-9PrivateSubForm_Click()582.素数问题

素数即质数,是指除了能被1和自身整除而不能被其他任何数整除的数。例8-10

判断整数x是否是素数。根据素数的定义,只需用2到n-1去除n,如果都除不尽则n是素数,否则,只要其中有一个数能除尽则n不是素数。也可以理解为,在2到n-1中寻找n的因子,若找不到则n是素数,否则n不是素数。2.素数问题素数即质数,是指除了能被1和自身整除而不能被其59例8-10PrivateSubCommand1_Click()DimxAsInteger,iAsIntegerx=Val(Text1)Ifx>1ThenFori=2Tox-1IfxModi=0ThenExitFor'判断x是否能被i整除,即i是否是x的因子NextiIfi=xThenMsgBoxx&"是素数"ElseMsgBoxx&"不是素数"EndIfElseMsgBox"x必须大于1"EndIfEndSub例8-10PrivateSubCommand1_Clic60例8-10改进:将搜索范围缩小到[2,]之间

k=Sqr(x)'这里进行自动转换,等价于四舍五入取整Fori=2TokIfxModi=0ThenExitForNextiIfi>kThenMsgBoxx&"是素数"ElseMsgBoxx&"不是素数"EndIf例8-10改进:将搜索范围缩小到[2,]之间61例8-11例8-11

从键盘上输入一个正整数,找出大于或等于该数的第一个素数。

x=Val(Text1)Ifx>1ThenDoFori=2ToSqr(x)IfxModi=0ThenExitForNextiIfi>Round(Sqr(x))ThenExitDoElsex=x+1EndIfLoopLabel2.Caption=“>=x的第一个素数是:"&xElseMsgBox"x必须大于1"EndIf例8-11例8-11从键盘上输入一个正整数,找出大于或等628.6.4递推法(迭代法)

使用递推法来解决的问题中,前一个状态和后一个状态间存在着一定的函数关系。递推法的关键在于找到正确的函数关系,然后使用循环语句来实现。1.最大公约数和最小公倍数

2.Fibonacci数列

3.累加中的递推

4.迭代法求方程的近似根

8.6.4递推法(迭代法)使用递推法来解决的问题中,前631.最大公约数和最小公倍数

若已知整数x和y的最大公约数是k,则它们的最小公倍数是x×y/k。

求两个整数最大公约数的两种方法。

(1)辗转相除法(欧几里德算法)

(2)相减法

1.最大公约数和最小公倍数若已知整数x和y的最大公约数是k641.最大公约数和最小公倍数(1)辗转相除法(欧几里德算法)递推公式如下:算法描述如下:步骤1:输入两个自然数x、y,令x>=y。步骤2:求x除以y的余数r。步骤3:yx,ry。步骤4:若r≠0,则转步骤2,否则转步骤5。步骤5:输出x。1.最大公约数和最小公倍数(1)辗转相除法(欧几里德算法)算651.最大公约数和最小公倍数(2)相减法。递推公式如下:

两个数中从大数中减去小数,所得的差若与小数相等,则该数为最大公约数。若不等,对所得的差和小数,继续从大数中减去小数,……,直到两个数相等为止。

1.最大公约数和最小公倍数(2)相减法。两个数中从大数中减去66程序举例例8-12

用欧几里德算法求x和y的最大公约数。

Ifx<yThentemp=x:x=y:y=tempDo '求最大公约数r=xModyx=yy=rLoopWhiler<>0Text3.Text=CStr(x) '输出最大公约数程序举例例8-12用欧几里德算法求x和y的最大公约数。672.Fibonacci数列

兔子繁殖问题:如果每对兔子每月繁殖一对子兔,而子兔在出生后第2个月就有生殖能力,试问一对兔子一年能繁殖多少对兔子?

可以这样思考:第1个月后即第2个月时,一对兔子变成了两对兔子,其中一对是它本身,另一对是它生下的幼兔。第3个月时两对兔子变成了三对,其中一对是最初的一对,另一对是它刚生下来的幼兔,第三对是幼兔长成的大兔子。第4个月时,三对兔子变成了五对,第5个月时,五对兔子变成了八对,按此方法推算,第6个月是13对兔子,第7个月是21对兔子……

2.Fibonacci数列兔子繁殖问题:如果每对兔子每月繁682.Fibonacci数列裴波那契得到一个数列,人们将这个数列前面加上一项1,成为“裴波那契数列”,即1,1,2,3,5,8,13……。该数列的特点是从数列的第3项开始,每一项都等于前两项之和,用公式表示如下。算法描述如下:步骤1:将x1和x2的初值赋为1。步骤2:若x1符合条件,则输出x1;若不符合,则程序结束。步骤3:x1t;x1+x2x1;tx2。步骤4:转步骤2。

2.Fibonacci数列裴波那契得到一个数列,人们将这个数69程序举例例8-13

输出100以内的Fibonacci数列。

PrivateSubForm_Click()Dimx1AsInteger,x2AsInteger,tAsIntegerx1=1:x2=1Printx2;DoWhilex1<=100Printx1;t=x1x1=x1+x2x2=tLoopEndSub程序举例例8-13输出100以内的Fibonacci数列703.累加中的递推

在累加(乘)算法中,若ai序列的前后项之间存在数学关系(ai=f(ai-1))时,累加(乘)运算也可采用递推法来实现,这种递推也称为迭代法。使用迭代法求累加(乘)中通项ai时,可以避免每次都重新开始计算ai,大大提高程序的效率。3.累加中的递推在累加(乘)算法中,若ai序列的前后项之间71程序举例例8-14

用递推法求解

分析:通项,当k=i和i+1时,得得到两者之间的递推关系式如下:

程序举例例8-14用递推法求解分析:通项72例8-14参考代码如下:PrivateSubCmdcul_Click()DimxAsSingle,iAsIntegerDimsumAsSingle,tAsSinglex=Val(txtX.Text)i=1:t=x:sum=x '第1项的处理Dot=t*(-1)*x*x/(2*i*(2*i+1))'通项t的递推sum=sum+ti=i+1LoopUntilAbs(t)<10^(-6)txtResult.Text=Format(sum,"0.00000")EndSub例8-14参考代码如下:734.迭代法求方程的近似根

主要思想是从某个初值x0开始,根据迭代公式逐次产生更接近于真实解的x1,x2,……,直到某个x在一定精度下非常接近真实解,这个x就是解的近似值。

4.迭代法求方程的近似根主要思想是从某个初值x0开始,根据74程序举例例8-15

用牛顿迭代法求方程

的近似根(为止)。

牛顿迭代法的迭代公式是

,k=0,1,2,……,其中是对求导的结果。

本题中程序举例例8-15用牛顿迭代法求方程

的近似根(75例8-15程序代码如下:PrivateSubCommand1_Click()Dimx0AsSingle,x1AsSinglex1=Val(InputBox("请输入x的初值"))Dox0=x1x1=x0-(x0*Exp(x0)-1)/(Exp(x0)*(x0+1))LoopUntilAbs(x1-x0)<10^-5PrintFormat(x1,"0.0000000")EndSub当程序输入x的初值为0.5时,结果显示近似根为0.5671433。例8-15程序代码如下:768.6.5字符串遍历

字符串的遍历是指逐个访问字符串中的每一个字符,并对其进行指定的操作。

1.完全遍历

2.回文字符串

8.6.5字符串遍历字符串的遍历是指逐个访问字符串中的771.完全遍历

一般的,我们总是从字符串的第一个字符开始访问,直到最后一个字符,称为字符串的完全遍历。经常采用以下语句结构进行字符串的遍历。

Fori=1ToLen(str)

…‘对str中第i个字符Mid(str,i,1)进行处理

Nexti1.完全遍历一般的,我们总是从字符串的第一个字符开始访问,78程序举例例8-16

统计用户输入的字符串中字母字符、数字字符和其他字符的数量。

程序举例例8-16统计用户输入的字符串中字母字符、数字字79PrivateSubCmdCount_Click() '统计按钮的单击事件DimsAsString,iAsInteger'设置3个计数器,分别记录字母、数字和其他字符的统计数量Dimn_charAsInteger,n_digitalAsInteger,n_otherAsIntegers=Text1.Text '接收用户输入的一串字符Fori=1ToLen(s)'从第1个字符开始统计到最后1个字符SelectCaseMid(s,i,1) '对每1个输入的字符进行判断分类Case"A"To"Z","a"To"z"n_char=n_char+1 '字母计数器+1Case"0"To"9"n_digital=n_digital+1 '数字计数器+1CaseElsen_other=n_other+1 '其他字符计数器+1EndSelectNexti'显示统计结果MsgBox“有”&n_char&“个字母,”&n_digital&“个数字,”&_

n_other&"个其他字符。"EndSubPrivateSubCmdCount_Click()802.回文字符串

回文字符串是指该字符串正读和反读都一样。如“aba”、“abba”、“处处飞花飞处处”、“珠联璧合璧联珠”等都属于回文字符串。例8-17

判断用户输入的字符串是否是回文。

两种方法:(1)按定义判断(2)首尾字符的成对比较

2.回文字符串回文字符串是指该字符串正读和反读都一样。81例8-17(1)按定义判断先求出字符串的反序字符串,然后和原字符串比较,如果相等则是回文,否则不是回文。DimstrAsString,iAsInteger'以下求Text1中文本的反序串strFori=1ToLen(Text1)str=Mid(Text1,i,1)&strNextiIfstr=Text1ThenMsgBox"是回文"ElseMsgBox"不是回文"例8-17(1)按定义判断DimstrAsStrin822.回文字符串(2)首尾字符的成对比较将字符串折半比较,若每对字符都相等则是回文,否则只要有一对字符不等就不是回文。

DimiAsIntegerFori=1ToLen(Text1)\2IfMid(Text1,i,1)<>Mid(Text1,Len(Text1)-i+1,1)ThenExitForNextiIfi>Len(Text1)\2ThenMsgBox"是回文"ElseMsgBox"不是回文"2.回文字符串(2)首尾字符的成对比较DimiA838.6.6有限状态自动机

计算机工作者们提出了一种形象的方式描述这种动态过程,它可以清楚地反映一个“系统”的状态、状态转换的条件、转换时的动作等等。

这种抽象模型称为自动机。8.6.6有限状态自动机计算机工作者们提出了一种形象的84程序举例例8-18

统计文章中共有多少英文单词。设单词间使用空格隔开,句中或句末使用逗号、句号、感叹号、问号。分析:当前字符是单词的首字符,则遇到新单词,这时应把计数器加一。当前字符不是空格,它是不是新词的开始还依赖于前一字符是否空格。∴处理步骤不能孤立进行,处理方式需要依赖于前面的历史情况。读入过程有两种不同的状态(相互转换):

①处在单词之外(如果遇到非空格字符,那就是新词)

②正处在某单词的内部(不会遇到新词)程序举例例8-18统计文章中共有多少英文单词。设单词间使85描述读入状态转换的自动机

INOUT读到空格字符,状态不变读到空格字符,转到OUT状态读到非空格字符,转到IN状态

counter=counter+1读到非空格字符,状态不变Flag=TrueFlag=False描述读入状态转换的自动机

INOUT读到空格字符,状态不变读86例8-18Fori=1ToLen(Text1)ch=Mid(Text1,i,1) 'ch为当前字符Ifch>="a"Andch<="z"Orch>="A"Andch<="Z"ThenIfflag=FalseThen '若前一字符不是字母flag=True 'OUT状态转换到IN状态counter=counter+1EndIfElseIfch=""Orch="."Orch=","Orch="!"Orch="?"Thenflag=False 'IN状态转换到OUT状态EndIfNextiMsgBox"共有"&counter&"个单词"例8-18Fori=1ToLen(Text1)878.6.6有限状态自动机素数问题另解:

Flag=True '逻辑型状态变量FlagFori=2ToSqr(x)IfxModi=0ThenFlag=False:ExitForNextiIfFlagThen '等价于IfFlag=TrueThenMsgBoxx&"是素数"ElseMsgBoxx&"不是素数"EndIf8.6.6有限状态自动机素数问题另解:888.6.7进制转换

例8-19

实现D进制数整数(D<=16)和十进制数整数的互换

1.D进制整数转换成10进制整数

2.10进制整数转换成D进制整数

8.6.7进制转换例8-19实现D进制数整数(D<891.D进制整数转换成10进制整数

由于D进制数只能表示成字符串,因此这又是一个对字符串的操作运算。若D进制数表示成akak−1…a2a1a0,则转换成十进制数据的方法是多项式法,如下所示。

也可以表示成

其中后一种表达式中避免了对基数D的幂指数的求解,且将求和归结为求若干次ai·D+ai−1的过程,这是较为常用的方法。

1.D进制整数转换成10进制整数由于D进制数只能表示成字符90PrivateSubCmdD_10_Click()DimsAsString,chAsString*1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论