我很久没有考虑过递归,所以请耐心等待我。
我基本上需要编写一个子程序,如果它们总计给定的数字,它将输出所有数字序列。迭代方法将在以下部分中显示
Sub IterFunc()
For i = 1 To 5
For j = 1 To 5
For k = 1 To 5
If i + j + k = 4 Then
Debug.Print i & ", " & j & ", " & k
End If
Next k
Next j
Next i
End Sub
如果序列由3个整数组成,则可以正常工作,但它不适用于序列中任意数量的整数。因此需要一种递归方法。以下是我尝试重写子例程的递归版本
Sub RecuFunc(ByRef tot As Long)
For i = 1 To 5
tot = tot + i
If tot = 5 Then
Debug.Print i
ElseIf tot < 5 Then
Call RecuFunc(tot)
ElseIf tot > 5 Then
Call RecuFunc(tot - i)
End If
Next i
End Sub
Sub test2()
Call RecuFunc(0)
End Sub
很快就出现了几个问题:a)我不太确定如何在总匹配时存储序列来输出它b)似乎我需要以某种方式&#34;重置&#34;变量tot
,但我的方法似乎不起作用。
任何想法都会很棒。如果我的问题很原始,我会道歉。
谢谢!
答案 0 :(得分:1)
这是一个递归函数,给定一个整数n
和一个目标值target
(假设为> 0),返回一个表格的所有字符串的集合,例如: "1 + 2 + 1 + 1"
,其中总和中的数字在1,...,n范围内,并且它们与目标相加。集合是一种自然的数据结构,使用字符串的优势在于它可以很容易地将新条款用于总和:
Function IntSums(n As Long, target As Long) As Collection
Dim sums As New Collection
Dim partialSums As Collection
Dim i As Long, m As Long, sum As Variant
If target = 1 Then
sums.Add target
Set IntSums = sums
Exit Function
End If
m = IIf(n < target, n, target) 'm is min(n,target)
For i = 1 To m
If i = target Then
sums.Add Trim(Str(target))
Else
Set partialSums = IntSums(n, target - i)
For Each sum In partialSums
sums.Add i & " + " & sum
Next sum
End If
Next i
Set IntSums = sums
End Function
测试功能:
Sub test()
Dim s As Variant, sum As Variant
Set s = IntSums(5, 5)
For Each sum In s
Debug.Print sum
Next sum
End Sub
输出:
1 + 1 + 1 + 1 + 1
1 + 1 + 1 + 2
1 + 1 + 2 + 1
1 + 1 + 3
1 + 2 + 1 + 1
1 + 2 + 2
1 + 3 + 1
1 + 4
2 + 1 + 1 + 1
2 + 1 + 2
2 + 2 + 1
2 + 3
3 + 1 + 1
3 + 2
4 + 1
5
答案 1 :(得分:1)
我认为您要做的是列出具有有限数量部件的数字的分区。这是JavaScript中的一种递归,这种语法的语法与C:
的距离不太远function ps(n,k,max,r){
if (n == 0){
console.log(r.substr(1));
return;
}
for (var i=Math.min(max,n-k+1); i*k>=n; i--){
ps(n - i,k - 1,i,r + "," + i);
}
}
ps(8,3,8,"")
/*
6,1,1
5,2,1
4,3,1
4,2,2
3,3,2
*/
对于不受限制的版本,我们会移除k
:
function ps(n,max,r){
if (n == 0){
console.log(r.substr(1));
}
for (var i=Math.min(max,n); i>0; i--){
ps(n - i,i,r + "," + i);
}
}
ps(8,8,"")
答案 2 :(得分:0)
这里也许不是一个完整的答案 - 我不了解VB - 但是要让你开始朝着正确的方向前进。几个观察结果:首先,通常是迭代的&gt;递归。其次,你正在做蛮力,可能找到一种更有效的方法。考虑将10的总值分成三个整数的总和: 10 = 3 + 5 + 2 =(1 + 1 + 1)+(1 + 1 + 1 + 1 + 1)+(1 + 1) 10 = 4 + 5 + 1 =(1 + 1 + 1 + 1)+(1 + 1 + 1 + 1 + 1)+(1) 如您所见,基本上您正在转动括号所在的位置。就递归而言,可以通过减去&#34; i&#34;来实现10到3的总和。从10开始,然后递归地将(10-i)分成两个总和。