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);
        }
    }
}

VB.网络递归问题

这是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循环是更好的选择。您在第一次进入循环时确定迭代的次数。


为什么递归是无意义的?因为在这个函数实际返回的任何点,它已经沿着整个列表工作了。在递归地调用了函数之后,你不应该做的是继续遍历列表。

并且当您进行递归调用时,您强制它在列表的开始处重新开始,您的当前调用已经检查过了。