VB.网络递归问题
本文关键字:问题 递归 网络 VB | 更新日期: 2023-09-27 18:01:23
我在c#中有一个运行良好的递归函数。但是当我把它转换成VB。Net,它给出了索引错误。奇怪的是,当它在VB中调试时,代码会转到'End Sub'行,并再次进入递归函数调用。知道为什么会这样吗?
这是一个简单的函数,用于从组列表中更正已排序的年龄组。请看下面的代码:
最终预期组为0-10、30-60和75-90。
Public Class AgeGroup
Public Lower As Integer
Public Higher As Integer
End Class
Public Class RngTest
Public Sub MakeUniqueRanges(ByVal ranges As List(Of AgeGroup))
For i As Integer = 0 To ranges.Count - 2
Dim first As AgeGroup = ranges(i)
Dim second As AgeGroup = ranges(i + 1)
If first.Higher > second.Lower Then
'range is mixed..construct a new range by mixing the two ranges
Dim newRange As New AgeGroup()
newRange.Lower = first.Lower
newRange.Higher = second.Higher
'delete the existing 2 ranges
ranges.RemoveAt(i)
ranges.RemoveAt(i)
ranges.Insert(i, newRange)
MakeUniqueRanges(ranges)
End If
Next
End Sub
End Class
Module RngModule
Sub Main()
Dim ranges As New List(Of AgeGroup)()
ranges.Add(New AgeGroup() With {.Lower = 0, .Higher = 10})
ranges.Add(New AgeGroup() With {.Lower = 30, .Higher = 40})
ranges.Add(New AgeGroup() With {.Lower = 35, .Higher = 50})
ranges.Add(New AgeGroup() With {.Lower = 45, .Higher = 60})
ranges.Add(New AgeGroup() With {.Lower = 75, .Higher = 90})
Dim test As New RngTest()
test.MakeUniqueRanges(ranges)
Console.ReadLine()
End Sub
End Module
这是一个很好的c#方法
static void MakeUniqueRanges(List<AgeGroup> ranges)
{
for (int i = 0; i < ranges.Count - 1; i++)
{
AgeGroup first = ranges[i];
AgeGroup second = ranges[i + 1];
if (first.Higher > second.Lower)
{
//range is mixed..
AgeGroup newRange = new AgeGroup();
newRange.Lower = first.Lower;
newRange.Higher = second.Higher;
ranges.RemoveAt(i);
ranges.RemoveAt(i);
ranges.Insert(i, newRange);
MakeUniqueRanges(ranges);
}
}
}
这是c#的非递归版本:
static void MakeUniqueRanges(List<AgeGroup> ranges)
{
for (int i = 0; i < ranges.Count - 1; i++)
{
AgeGroup first = ranges[i];
AgeGroup second = ranges[i + 1];
while (first.Higher > second.Lower)
{
//range is mixed..
AgeGroup newRange = new AgeGroup();
newRange.Lower = first.Lower;
newRange.Higher = second.Higher;
ranges.RemoveAt(i); //Remove "first"
ranges[i] = newRange; //Replace "second"
if (i == ranges.Count - 1) return; //Are we now at the end of the list?
first = ranges[i];
second = ranges[i + 1];
}
}
}
这应该是VB的等效:
Public Sub MakeUniqueRanges(ByVal ranges As List(Of AgeGroup))
Dim i as Integer = 0
While i <= ranges.Count - 2
Dim first As AgeGroup = ranges(i)
Dim second As AgeGroup = ranges(i + 1)
While first.Higher > second.Lower
'range is mixed..construct a new range by mixing the two ranges
Dim newRange As New AgeGroup()
newRange.Lower = first.Lower
newRange.Higher = second.Higher
ranges.RemoveAt(i) 'Remove "first"
ranges(i) = newRange
If i = ranges.Count - 1 Then Return
first = ranges(i)
second = ranges(i + 1)
End While
i = i + 1
End While
End Sub
那么,为什么你最初的尝试没有成功呢?因为在VB中,要执行的迭代次数在您第一次启动循环时是固定的。在循环中,end
值不会每次都重新评估。所以这段代码:
Dim i = 5
For j = 0 To i
i = 1
Console.WriteLine("Hello")
Next
打印Hello
6次。而在c# for
循环中,终止条件在每次循环中都被完整地重新计算。
看到…未来:
While...End While
Statement (Visual Basic)或Do...Loop
Statement (Visual Basic)在您不知道在循环中运行语句的次数时工作得很好。但是,当您希望运行循环的特定次数时,For...Next
循环是更好的选择。您在第一次进入循环时确定迭代的次数。
为什么递归是无意义的?因为在这个函数实际返回的任何点,它已经沿着整个列表工作了。在递归地调用了函数之后,你不应该做的是继续遍历列表。
并且当您进行递归调用时,您强制它在列表的开始处重新开始,您的当前调用已经检查过了。