11.累加与连乘1、算法说明[分析]累加形式:V=V+e连乘形式:V=V*e其中:V是变量,e是递增表达式。累加和连乘一般通过循环结构来实现。注意:需在执行循环体前对变量V赋初值。一般累加时置初值0;连乘时置初值为1。[举例]求N!的结果。PrivateSubCommand1_Click()Dimn%,i%,s&n=Val(InputBox(输入n))s=1Fori=1Tons=s*iNextiPrintsEndSub[应用举例]根据下列公式,求自然对数e的的近似值。要求:误差小于0.00001PrivateSubCommand1_Click()Dimi%,n&,t!,e!e=2i=1t=1DoWhilet0.00001i=i+1t=t/ie=e+tLoopPrint计算了;i;项目和是:;ePrintExp(1)‘与上句输出值进行对比以证明算法的正确性EndSub22.最值问题1、算法说明在若干数中求最大值,一般先取第一个数为最大值的初值(即假设第一个数为最大值),然后,在循环体内将每一个数与最大值比较,若该数大于最大值,将该数替换为最大值,直到循环结束。求最小值的方法类同。求若干数平均值,实质上就是先求和,再除以这些数的个数。应用举例:随机产生n个1-100(包括1和100)的数,求它们的最大值、最小值和平均值。PrivateSubCommand1_Click()Dimn%,i%,min%,max%,aver!,s%n=Val(InputBox(输入个数:))s=Int(Rnd*100)+1max=s:min=s:aver=sPrint第1个数是:&sFori=2Tons=Int(Rnd*100)+1Print第&i&个数是:&sIfsmaxThenmax=sIfsminThenmin=saver=aver+sNextiaver=aver/nPrintmax=;max;min=;min;aver=;averEndSub解题技巧:最大值、最小值、平均值类型题目往往和数组放在一起考!有的不仅求这些值,还要对具有最大值或者最小值的行或列或者某个元素进行处理,这时就要在记录最大、最小值时,同时记录该值所在的行号和列号。33.素数问题1、算法说明素数(质数):就是一个大于等于2的整数,并且只能被1和本身整除,而不能被其他整数整除的数。判别某数m是否是素数的经典算法是:对于m,从I=2,3,4,……,m-1依次判别能否被I整除,只要有一个能整除,m就不是素数,否则m是素数。PrivateFunctionsushu(ByValnAsInteger)AsBooleanDimiAsIntegerFori=2Ton-1If(nModi)=0ThenExitForNextIIfI=nthensushu=TrueEndFunction很显然,实际上,我们可以改进上面PrivateFunctionsushu(ByValnAsInteger)AsBooleanDimiasIntegerFori=2toInt(Sqr(n))IfXModi=0ThenExitFunctionNextisushu=TrueEndFunction这样可以很好的提高效率。以上判断是否为素数的代码务必识记!应用举例:求100-200之内素数。PrivateSubCommand1_Click()DimjAsIntegerForj=100To200Ifsushu(j)=TrueThenPrintjEndIfNextjEndSub实例说明编程题:找出10000以内所有可以表示为两个平方数和的素数。思路:首先找10000以内的所有素数,对于每个素数判断其是否可以表示为两个平方数之和(即对于任意小于该素数shu的数I,如果I和shu-I均为平方数,则说明其可以表示为两个平方数之和。)判断数I是否为平方数的方法:Sqr(i)=Int(Sqr(i))PrivateSubCommand1_Click()DimjAsInteger,mAsInteger,nAsIntegerForj=2To100004Ifsushu(j)=TrueThenIfpf(j,m,n)=TrueThenList1.AddItemj&=&m&+&nEndIfEndIfNextjEndSubPrivateFunctionpf(ByValshuAsInteger,mAsInteger,nAsInteger)AsBooleanDimiAsLongFori=1Toshu-1If(Sqr(i)=Int(Sqr(i)))And(Sqr(shu-i)=Int(Sqr(shu-i)))Thenpf=Truem=in=shu-iExitFunctionEndIfNextEndFunction54.进制转换1、算法说明1)十进制正整数m转换为R(2-16)进制的字符串。思路:将m不断除r取余数,直到商为0,将余数反序即得到结果。算法实现:PrivateFunctionTran(ByValmAsInteger,ByValrAsInteger)AsStringDimStrDtoRAsString,nAsIntegerDoWhilemon=mModrm=m\rIfn9ThenStrDtoR=Chr(65+n-10)&StrDtoRElseStrDtoR=n&StrDtoREndIfLoopTran=StrDtoREndFunction2)R(2-16)进制字符串转换为十进制正整数。思路:R进制数每位数字乘以权值之和即为十进制数。算法实现:PrivateFunctionTran(ByValsAsString,ByValrAsInteger)AsIntegerDimiasInteger,nAsInteger,decAsIntegers=UCase(Trim(s))Fori=1ToLen(s)IfMid(s,i,1)=AThenn=Asc(Mid(s,i,1))-Asc(A)+10Elsen=Val(Mid(s,i,1))EndIfdec=dec+n*r^(Len(s)-i)NextiTran=decEndFunction解题技巧:进制转化的原理要清楚,同时编写代码时候要留意16进制中的A-F字符的处理。算法(五)约数因子--65.最大公约数、最小公倍数1、算法说明1)最大公约数:用辗转相除法求两自然数m、n的最大公约数。(1)首先,对于已知两数m、n,比较并使得mn;(2)m除以n得余数r;(3)若r=0,则n为求得的最大公约数,算法结束;否则执行步骤(4)(4)mnnr再重复执行(2)算法实现:循环PrivateFunctionGCD(ByValmAsLong,ByValnAsLong)AsLongDimtempAsLong,rAsLongIfmnThentemp=m:m=n:n=tempDor=mModnIfr=0ThenExitDom=nn=rLoopGCD=nEndFunction算法实现:递归PrivateFunctionGCD(ByValmAsLong,ByValnAsLong)AsLongDimtempAsLong,rAsLongIfmnThentemp=m:m=n:n=tempr=mModnIfr=0ThenGCD=nElsem=nn=rGCD=GCD(m,n)EndIfEndFunction2)最小公倍数:m×n÷最大公约数3)互质数:最大公约数为1的两个正整数解题技巧:该算法需要识记!这种类型题目的扩展是约数和因子题型。分析步骤:m=24,n=924与9r=mModn=6r≠0,m=9,n=6r=mModn=3r≠0,m=6,n=3r=mModn=03为最大公约数。分析步骤:10与5m=10,n=5r=mModn=0所以n(n=5)为最大公约数76.排序1、算法说明1)选择法排序(1)从n个数中选出最小数的下标,出了循环,将最小数与第一个数交换位置;(2)除第一个数外,在剩下的n-1个数中再按方法(1)选出次小的数,与第二个数交换位置;(3)以此类推,最后构成递增序列。譬如:869327第一轮交换后269387第二轮交换后239687第三轮交换后236987第四轮交换后236789第五轮无交换236789程序代码如下:PrivateSubxzPaiXu(a()AsDouble,shengAsBoolean)'a为需要排序的数组,sheng为True则为升序排列,为False,则为降序排列。DimiAsInteger,jAsInteger,tempAsDouble,mAsIntegerFori=LBound(a)ToUBound(a)-1'进行数组大小-1轮比较m=i'在第i轮比较时,假定第i个元素为最值元素Forj=i+1ToUBound(a)'在剩下的元素中找出最值元素的下标并赋值给mIfshengThen'若为升序,则m记录最小元素下标,否则记录最大元素下标Ifa(j)a(m)Thenm=jElseIfa(j)a(m)Thenm=jEndIfNextjtemp=a(i):a(i)=a(m):a(m)=temp'将最值元素与第i个元素交换NextiEndSub调用该过程示例:OptionBase1PrivateSubCommand1_Click()Dimb(6)AsDoubleb(1)=8:b(2)=6:b(3)=9:b(4)=3:b(5)=2:b(6)=7CallxzPaiXu(b,True)Fori%=1To6Printb(i)NextEndSub82)冒泡法排序选择排序法在每一轮排序时找最值元素的下标,出了内循环(一轮排序结束),再交换最小数的位置;而冒泡法在每一轮排序时将相邻的数比较,当次序不对就交换位置,出了内循环,最值数已经冒出。譬如:869327869327869237862937826937286937….238697….236879….236789….236789程序代码如下:PrivateSubmpPaiXu(a()AsDouble,shengAsBoolean)'a为需要排序的数组,sheng为True则为升序排列,为False,则为降序排列。DimiAsInteger,jAsInteger,tempAsDoubleFori=LBound(a)ToUBound(a)-1'进行n-1轮比较Forj=UBound(a)Toi+1Step-1'从n到i个元素两两进行比较IfshengThen'若次序不对,马上进行交换Ifa(j)a(j-1)Thentemp=a(j):a(j)=a(j-1):a(j-1)=tempEndIfElseIfa(j)a(j-1)Thentemp=a(j):a(j)=a(j-1):a(j-1)=tempEndIfEndIfNextj'出了内循环,一轮排序结束,最值元素冒到最上边NextiEndSub数组元素插入删除--第一轮排序:从右至左将最小的数移至最右边。97.在数组中插入或删除元素1、算法说明数组中元素的插入和删除一般是在已固定序列的数组中插入或删除一个元素,使得插入或删除操作后的数组还是有序的。基本思路:首先要找到插入位置或要删除的元素。1)插入代码如下:PrivateSubCommand1_Click()Dima(10)AsInteger,iAsInteger,kAsIntegerFori=0To9'生成数组a(i)=i*3+1Printa(i);NextiPrintPrint插入14Fork=0To9'查找插入14在数组中的位置If14a(k)ThenExitForNextkFori=9TokStep-1'从最后元素开始逐个后移,腾出位置a(i+1)=a(i)Nextia(k)=14'插入数14Fori=0To10Printa(i);NextiPrintEndSub2)删除K代码如1471013161922252810下:Dima()asinteger….ReDima(1ton)…Fori=k+1tona(i-1)=a(i)Ne