递归vba.docx
- 文档编号:24742274
- 上传时间:2023-06-01
- 格式:DOCX
- 页数:24
- 大小:42.31KB
递归vba.docx
《递归vba.docx》由会员分享,可在线阅读,更多相关《递归vba.docx(24页珍藏版)》请在冰豆网上搜索。
递归vba
递归是怎么一回事?
递归通俗的讲就是一个函数在其代码中反复调用自身。
你应该知道菲波纳契数列,这个数列的定义是:
f(x)=1(x=1)
f(x)=2(x=2)
f(x)=f(x-1)+f(x-2)(x>2)
也就是说从第三项开始的每一项的值都等于是前两项之和。
这在数学中叫递推数列--高中数学内容。
说到本质的话,递归是一段程序的代码反复效用,把程序的参数等变量保存在一个堆栈里,直到到了边界条件以后再层层返回,将堆栈中的数据弹出计算,最后得到结果。
补充一下,递规包括直接递规和间接递规。
直接递规是指在代码中反复调用自身,而间接递规是间接地调用自身。
递归概念最通俗的形象比喻:
打个比方吧,递归法好比是一个军队要通过一个迷宫,到了第一个分岔口,有3条路,将军命令3个小队分别去探哪条路能到出口,3个小队沿着3条路分别前进,各自到达了路上的下一个分岔口,于是小队长再分派人手各自去探路?
?
只要人手足够(对照而言,就是计算机的堆栈足够),最后必将有人找到出口,从这人开始只要层层上报直属领导,最后,将军将得到一条通路。
所不同的是,计算机的递归法是把这个并行过程串行化了。
递归算法的基本思想是:
把规模大的、较难解决的问题变成规模较小的、易解决的同一问题。
规模较小的问题又变成规模更小的问题,并且小到一定程度可以直接得出它的解,从而得到原来问题的解。
什么是递归函数(recursivefunction)
递归函数即自调用函数,在函数体内部直接或间接地自己调用自己,即函数的嵌套调用是函数本身。
VB函数递归使用实例链接:
用VB函数Dir实现递归搜索目录实例链接:
遍历所有文件夹的递归函数(epower2002)
SubMain()
ProcessDirectory("E:
\MyDocuments")
Console.ReadLine()
EndSub
PrivateSubProcessDirectory(ByValtargetDirectoryAsString)
IfDirectory.Exists(targetDirectory)Then
IfDirectory.GetFileSystemEntries(targetDirectory).Length=0Then
'Emptyfolder
Console.WriteLine("Folder"&targetDirectory&"isempty")
Else
'Recursesubdirectoriesofthisdirectory
DimsubdirectoryAsString
DimsubdirectoryEntriesAsString()=Directory.GetDirectories(targetDirectory)
ForEachsubdirectoryInsubdirectoryEntries
Console.WriteLine("Folderis"&subdirectory)
ProcessDirectory(subdirectory)
Nextsubdirectory
EndIf
EndIf
EndSub
查找给定文件夹下的全部文件,递归调用堆栈溢出:
链接:
递归算法
用自身的结构来描述自身,称递归
VB允许在一个Sub子过程和Function过程的定义内部调用自己,即递归Sub子过程和递归Function函数。
递归处理一般用栈来实现,每调用一次自身,把当前参数压栈,直到递归结束条件;然后从栈中弹出当前参数,直到栈空。
递归条件:
(1)递归结束条件及结束时的值;
(2)能用递归形式表示,且递归向终止条件发展。
例:
编fac(n)=n!
的递归函数
Functionfac(nAsInteger)AsInteger
Ifn=1Then
fac=1
Else
fac=n*fac(n-1)
EndIf
EndFunction
递归程序的基本步骤
每一个递归程序都遵循相同的基本步骤:
1.初始化算法。
递归程序通常需要一个开始时使用的种子值(seedvalue)。
要完成此任务,可以向函数传递参数,或者提供一个入口函数,这个函数是非递归的,但可以为递归计算设置种子值。
2.检查要处理的当前值是否已经与基线条件相匹配。
如果匹配,则进行处理并返回值。
3.使用更小的或更简单的子问题(或多个子问题)来重新定义答案。
4.对子问题运行算法。
5.将结果合并入答案的表达式。
6.返回结果。
递归算法的基本思想
递归算法一般都包含三个基本部分:
1、当前问题Qn
2、从较简单的问题Qn-1到Qn的操作Opn-1
3、已解决的基础问题Q0
这样,当前问题Qn就可以被一步一步化简为:
Qn
Opn-1+Qn-1
...
Opn-1+Opn-2+Opn-3...+Q0
这样一些列确定的步骤而最终得到解决。
递归算法解题的一般思路
在一个子程序(过程或函数)的定义中又直接或间接地调用该子程序本身,称为递归。
递归是一种非常有用的程序设计方法。
用递归算法编写的程序结构清晰,具有很好的可读性。
递归算法的基本思想是:
把规模大的、较难解决的问题变成规模较小的、易解决的同一问题。
规模较小的问题又变成规模更小的问题,并且小到一定程度可以直接得出它的解,从而得到原来问题的解。
利用递归算法解题,首先要对问题的以下三个方面进行分析:
一、决定问题规模的参数。
需要用递归算法解决的问题,其规模通常都是比较大的,在问题中决定规模大小(或问题复杂程度)的量有哪些?
把它们找出来。
二、问题的边界条件及边界值。
在什么情况下可以直接得出问题的解?
这就是问题的边界条件及边界值。
三、解决问题的通式。
把规模大的、较难解决的问题变成规模较小、易解决的同一问题,需要通过哪些步骤或等式来实现?
这是解决递归问题的难点。
把这些步骤或等式确定下来。
把以上三个方面分析好之后,就可以在子程序中定义递归调用。
其一般格式为:
if 边界条件1成立 then
赋予边界值1
【elseif 边界条件2成立 then
赋予边界值2
┇ 】
else
调用解决问题的通式
endif
例1:
计算勒让德多项式的值
x、n由键盘输入。
分析:
当n=0或n=1时,多项式的值都可以直接求出来,只是当n>1时,才使问题变得复杂,决定问题复杂程度的参数是n。
根据题目提供的已知条件,我们也很容易发现,问题的边界条件及边界值有两个,分别是:
当n=0时Pn(x)=1和当n=1时Pn(x)=x。
解决问题的通式是:
Pn(x)=((2n-1)Pn-1(x)-(n-1)Pn-2(x))/n。
接下来按照上面介绍的一般格式定义递归子程序。
functionPnx(nasinteger)
ifn=0then
Pnx=1
elseifn=1then
Pnx=x
else
Pnx=((2*n-1)*Pnx(n-1)-(n-1)*Pnx(n-2))/n
endif
endfunction
例2:
Hanoi塔问题:
传说印度教的主神梵天创造世界时,在印度北部佛教圣地贝拿勒斯圣庙里,安放了一块黄铜板,板上插着三根宝石针,在其中一根宝石针上,自下而上地放着由大到小的64个金盘。
这就是所谓的梵塔(Hanoi),如图。
梵天要求僧侣们坚持不渝地按下面的规则把64个盘子移到另一根针上:
(1) 一次只能移一个盘子;
(2) 盘子只许在三根针上存放;
(3) 永远不许大盘压小盘。
梵天宣称,当把他创造世界之时所安放的64个盘子全部移到另一根针上时,世界将在一声霹雳声中毁灭。
那时,他的虔诚的信徒都可以升天。
要求设计一个程序输出盘子的移动过程。
分析:
为了使问题更具有普遍性,设共有n个金盘,并且将金盘由小到大依次编号为1,2,…,n。
要把放在s(source)针上的n个金盘移到目的针o(objective)上,当只有一个金盘,即n=1时,问题是比较简单的,只要将编号为1的金盘从s针上直接移至o针上即可。
可定义过程move(s,1,o)来实现。
只是当n>1时,才使问题变得复杂。
决定问题规模的参数是金盘的个数n;问题的边界条件及边界值是:
当n=1时,move(s,1,o)。
当金盘不止一个时,可以把最上面的n-1个金盘看作一个整体。
这样n个金盘就分成了两个部分:
上面n-1个金盘和最下面的编号为n的金盘。
移动金盘的问题就可以分成下面三个子问题(三个步骤):
(1)借助o针,将n-1个金盘(依照上述法则)从s针移至i(indirect)针上;
(2)将编号为n的金盘直接从s针移至o针上;
(3)借助s针,将i针上的n-1个金盘(依照上述法则)移至o针上。
如图
其中第二步只移动一个金盘,很容易解决。
第一、第三步虽然不能直接解决,但我们已经把移动n个金盘的问题变成了移动n-1个金盘的问题,问题的规模变小了。
如果再把第一、第三步分别分成类似的三个子问题,移动n-1个金盘的问题还可以变成移动n-2个金盘的问题,同样可变成移动n-3,…,1个金盘的问题,从而将整个问题加以解决。
这三个步骤就是解决问题的通式,可以以过程的形式把它们定义下来:
hanoi(n-1,s,o,i)
move(s,n,o)
hanoi(n-1,i,s,o)
参考程序如下:
declaresubhanoi(n,s,i,o)
declaresubmove(s,n,o)
input"Howmanydisks?
",n
s=1
i=2
o=3
callhanoi(n,s,i,o)
end
subhanoi(n,s,i,o)
rem递归子程序
ifn=1then
callmove(s,1,o)
else
callhanoi(n-1,s,o,i)
callmove(s,n,o)
callhanoi(n-1,i,s,o)
endif
endsub
submove(s,n,o)
print"movedisk";n;
print"from";s;"to";o
endsub
递归找迷宫
EXCELVBA]EXCEL中用递归实现任意n(3≤n≤256)阶幻方
本文Tag:
excelvbaexcel递归幻方
作者:
northwolves来源:
发表于4个月以前
下面代码将实现任意n(3≤n≤256)阶幻方,显示在EXCEL的A1:
IV256中Submagicsquare(ByValnAsLong,ByRefmatrix())DimiAsLong,jAsLong,kAsLong,pAsLong,a(),tempAsNewCollectionReDimmatrix(1To256,1To256)Ifn<3ThenMsgBox"nmustbelargerthan2!
":
ExitSubIfnMod4=0ThenReDima(1Ton,1Ton)ReDimb(1Ton,1Ton)Fori=1TonForj=1Tonmatrix(i,j)=IIf((iMod4)\2=(jMod4)\2,n*n+1-(i-1)*n-j,(i-1)*n+j)NextNextElseIfnMod4=2Thenp=n/2ReDima(1Top,
EXCELVBA]EXCEL中用递归实现任意n(3≤n≤256)阶幻方
下面代码将实现任意n(3≤n≤256)阶幻方,显示在EXCEL的A1:
IV256中
Submagicsquare(ByValnAsLong,ByRefmatrix())
DimiAsLong,jAsLong,kAsLong,pAsLong,a(),tempAsNewCollection
ReDimmatrix(1To256,1To256)
Ifn<3ThenMsgBox"nmustbelargerthan2!
":
ExitSub
IfnMod4=0Then
ReDima(1Ton,1Ton)
ReDimb(1Ton,1Ton)
Fori=1Ton
Forj=1Ton
matrix(i,j)=IIf((iMod4)\2=(jMod4)\2,n*n+1-(i-1)*n-j,(i-1)*n+j)
Next
Next
Else
IfnMod4=2Then
p=n/2
ReDima(1Top,1Top)
magicsquarep,a
Fori=1Top
Forj=1Top
matrix(i,j)=a(i,j)
matrix(i+p,j)=a(i,j)+3*p*p
matrix(i,j+p)=a(i,j)+2*p*p
matrix(i+p,j+p)=a(i,j)+p*p
Next
Next
Fori=1To(n-2)/4
temp.Addi
Next
Fori=3*(n-2)/4+1Ton
temp.Addi
Next
Fori=1Top
Forj=1Totemp.Count
k=matrix(i,temp(j))
matrix(i,temp(j))=matrix(i+p,temp(j))
matrix(i+p,temp(j))=k
Next
Next
Else
Forj=0Ton-1
Fori=0Ton-1
Ifj=0Thenmatrix(j+1,i+1)=IIf(i>=(n-1)/2,0,n*(n+1))+(i-(n-1)/2)*(n+2)+1
Ifj>0Thenmatrix(j+1,i+1)=1+(n*n+matrix(j,i+1)+IIf(matrix(j,i+1)Modn=0,0,n))Modn^2
Next
Next
EndIf
EndIf
EndSub
Submakemagicsquare()
Dimarr(),nAsLong
Randomize
n=CLng(InputBox("pleaseenteraninteger","infomation",3+Int(Rnd*254)))
magicsquaren,arr
Range("a1").Resize(256,256)=arr
Range("a1").Resize(256,256).Columns.AutoFit
EndSub
clamber
各位兄弟看看,VBA中的递归怎么不行呢?
PrivateSubCommandButton1_Click()
Dimaa,bbAsLong
aa=10
bb=f_1(aa)
[color=Red]''bb=f_1(aa)不行,''bb=f_1(10)就可以,可是我有时我想动态指定aa的值.[/color]
MsgBoxbb
EndSub
PublicFunctionf_1(tempAsLong)AsVariant
Iftemp=1Then
f_1=1
Else
f_1=temp*f_1(temp-1)
EndIf
EndFunction
2004-12-2115:
46clamber
报告的出错类型是"Bybefargumenttypemismatch"
2004-12-2115:
56apolloh
Dimaaaslong,bbAsLong
2004-12-2115:
59zgh058
如下:
PrivateSubCommandButton1_Click()
Dimaa,bbAsLong
aa=10
bb=f_1((aa))
MsgBoxbb
EndSub
PublicFunctionf_1(tempAsLong)AsVariant
Iftemp=1Then
f_1=1
Else
f_1=temp*f_1(temp-1)
EndIf
EndFunction
2004-12-2116:
01zgh058
还是3楼正解,我取了个捷径,只是在避免出错而已。
2004-12-2116:
16clamber
多谢!
3,4楼的前辈拉.
问题已经解决,但是为什么分两行声明就可以呢?
兄弟这段时间有一个任务--就是用VBA写个程序展开MRP中的BOM,以后还要麻烦大家.大家一定要帮忙呀!
2004-12-2214:
30wangmingbai
在vba里Dimaa,bbAsLong,意思是dimaaasVariant,bbAsLong。
2004-12-2315:
23jidanbing
长知识
T-SQL实现递归查询
表
ifexists(select*fromdbo.sysobjectswhereid=object_id(N'[dbo].[Test]')andOBJECTPROPERTY(id,N'IsUserTable')=1)
droptable[dbo].[Test]
GO
CREATETABLE[dbo].[Test](
[id][int]NOTNULL,
[Parentid][int]NULL
)ON[PRIMARY]
GO
查询语句
SELECTroot.id,root.ParentidFROMTestroot
WHEREroot.id=1
UNIONALL
SELECTsub.id,sub.Parentid
FROMTestsub,Testsuper
WHEREsub.Parentid=super.id
怎样实现sql中select递归
2007年01月26日
网友的提问:
如我有一表有如下字段,ID1,Id2,bz
怎么实现id2的值等于id1值的记录
如:
a1,b1,c1
b1,d1,c1
b1,e1,c1
d1,g1,c1
d1,t1,c1
g1,*,c1
t1,*,c1
..........
.......
网友1回答:
select*from表whereid2=id1
网友2回答:
是不是想更新表?
?
update表setid2=id1
网友3回答:
楼上抢先了:
)[:
(]
网友4回答:
递归啊,兄弟们,刚才那些还要100分
网友5回答:
能不能说清楚点呀
SQL在存储过程中使用递归
2007-01-2517:
55
递归的基本概念非常简单:
一段给定的代码对自身进行调用,直到某些边界条件得到满足。
在本文中,我们将演示如何在T-SQL中使用递归。
在我的眼中,递归是最为精致的程序结构之一。
我已经在许多场合用不同的编程语言实现过它。
递归的基本概念非常简单:
一段给定的代码对自身进行调用,直到某些边界条件得到满足。
我将通过下面的内容展示如何在T-SQL中使用递归。
我所用到的是递归的经典例子:
阶乘计算。
阶乘的意思就是将小于等于这一数字的所有数字相乘,直至乘到2。
例如,factorial(10)即等于10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2(你也可以加上“*1”,但似乎是多此一举)。
以下代码即实现了阶乘:
CREATE PROCEDURE [dbo].[Factorial_ap]
(
@Number Integer,
@RetVal Integer OUTPUT
)
AS
DECLARE @In Integer
DECLARE @Out Integer
IF @Number !
= 1
BEGIN
SELECT @In = @Number – 1
EXEC Factorial_ap @In, @Out OUTPUT
SELECT @RetVal = @Number * @Out
END
ELSE
BEGIN
SELECT @RetVal = 1
END
RETURN
GO
假设你需要计算factorial(n),这一过程将对自身调用(n-2)次。
SQL S
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 递归 vba