Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 有条件地剥离字符串右侧部分的最快方法_String_Vb.net_Split - Fatal编程技术网

String 有条件地剥离字符串右侧部分的最快方法

String 有条件地剥离字符串右侧部分的最快方法,string,vb.net,split,String,Vb.net,Split,我需要删除字符串末尾的数字部分。以下是一些例子: abcd1234->abcd a3bc45->a3bc kj3ih5->kj3ih 你明白了 我实现了一个函数,该函数为此目的运行良好 Function VarStamm(name As String) As String Dim i, a As Integer a = 0 For i = Len(name) To 1 Step -1 If IsNumeric(Mid(name, i, 1)) = Fals

我需要删除字符串末尾的数字部分。以下是一些例子:

abcd1234->abcd a3bc45->a3bc kj3ih5->kj3ih 你明白了

我实现了一个函数,该函数为此目的运行良好

Function VarStamm(name As String) As String
    Dim i, a As Integer
    a = 0
    For i = Len(name) To 1 Step -1
        If IsNumeric(Mid(name, i, 1)) = False Then
            i = i + 1
            Exit For
        End If
    Next i
    If i <= Len(name) Then
        VarStamm = name.Substring(0, i - 1)
    Else
        VarStamm = name
    End If
End Function
问题是:有没有速度更快、效率更高的方法来实现这一点?问题是,我在一个有300万次迭代的循环中调用这个函数,如果它更高效,那就更好了

我知道String.LastIndexOf方法,但当我需要字符串中最后一个连接的数字的索引时,我不知道如何使用它。

您可以使用Array.FindLastIndex,然后使用Substring:

您可以使用Array.findlastinex,然后使用子字符串:

考虑到您的函数VarStamm和timschmelter的一个名为VarStamm2的函数,下面是我编写的一个小型性能测试。我输入了一个任意的长字符串,右边有一个巨大的部分,并运行了一百万次函数

Module StackOverlow

    Sub Main()
        Dim testStr = "azekzoerjezoriezltjreoitueriou7657678678797897898997897978897898797989797"

        Console.WriteLine("RunTime :" + vbNewLine +
               " - VarStamm : " + getTimeSpent(AddressOf VarStamm, testStr) + vbNewLine +
               " - VarStamm2 : " + getTimeSpent(AddressOf VarStamm2, testStr))

    End Sub

    Function getTimeSpent(f As Action(Of String), str As String) As String
        Dim sw As Stopwatch = New Stopwatch()
        Dim ts As TimeSpan

        sw.Start()
        For i = 1 To 1000000
            f(str)
        Next
        sw.Stop()
        ts = sw.Elapsed
        Return String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            ts.Hours, ts.Minutes, ts.Seconds,
            ts.Milliseconds / 10)
    End Function

    Function VarStamm(name As String) As String
        Dim i, a As Integer
        a = 0
        For i = Len(name) To 1 Step -1
            If IsNumeric(Mid(name, i, 1)) = False Then
                i = i + 1
                Exit For
            End If
        Next i
        If i <= Len(name) Then
            VarStamm = name.Substring(0, i - 1)
        Else
            VarStamm = name
        End If
    End Function

    Function VarStamm2(name As String) As String
        Dim lastNonDigitIndex = Array.FindLastIndex(name.ToCharArray(), Function(c) Not Char.IsDigit(c))

        If lastNonDigitIndex >= 0 Then
            lastNonDigitIndex += 1
            Return name.Substring(0, lastNonDigitIndex)
        End If
        Return name
    End Function
End Module
是的,你应该选择他的答案,他的代码既漂亮又高效。

考虑到你的函数VarStamm和Tim Schmelter的函数VarStamm2,下面是我编写的一个小测试性能。我输入了一个任意的长字符串,右边有一个巨大的部分,并运行了一百万次函数

Module StackOverlow

    Sub Main()
        Dim testStr = "azekzoerjezoriezltjreoitueriou7657678678797897898997897978897898797989797"

        Console.WriteLine("RunTime :" + vbNewLine +
               " - VarStamm : " + getTimeSpent(AddressOf VarStamm, testStr) + vbNewLine +
               " - VarStamm2 : " + getTimeSpent(AddressOf VarStamm2, testStr))

    End Sub

    Function getTimeSpent(f As Action(Of String), str As String) As String
        Dim sw As Stopwatch = New Stopwatch()
        Dim ts As TimeSpan

        sw.Start()
        For i = 1 To 1000000
            f(str)
        Next
        sw.Stop()
        ts = sw.Elapsed
        Return String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            ts.Hours, ts.Minutes, ts.Seconds,
            ts.Milliseconds / 10)
    End Function

    Function VarStamm(name As String) As String
        Dim i, a As Integer
        a = 0
        For i = Len(name) To 1 Step -1
            If IsNumeric(Mid(name, i, 1)) = False Then
                i = i + 1
                Exit For
            End If
        Next i
        If i <= Len(name) Then
            VarStamm = name.Substring(0, i - 1)
        Else
            VarStamm = name
        End If
    End Function

    Function VarStamm2(name As String) As String
        Dim lastNonDigitIndex = Array.FindLastIndex(name.ToCharArray(), Function(c) Not Char.IsDigit(c))

        If lastNonDigitIndex >= 0 Then
            lastNonDigitIndex += 1
            Return name.Substring(0, lastNonDigitIndex)
        End If
        Return name
    End Function
End Module
是的,你应该选择他的答案,他的代码既漂亮又高效。

我怀疑Array.findlastedex方法实际上更快,所以我自己测试了它。我借用了Amessichel发布的测试代码,但添加了第三种方法:

Function VarStamm3(name As String) As String
    Dim i As Integer
    For i = name.Length - 1 To 0 Step -1
        If Not Char.IsDigit(name(i)) Then
            Exit For
        End If
    Next i
    Return name.Substring(0, i + 1)
End Function
它使用原始算法,但只是将旧的VB6样式的字符串方法替换为新的.NET等效方法。以下是我机器上的结果:

RunTime :
 - VarStamm : 00:00:07.92
 - VarStamm2 : 00:00:00.60
 - VarStamm3 : 00:00:00.23
正如您所看到的,您的原始算法已经进行了很好的调整。问题不在于循环。问题是Mid、IsNumeric和Len。因为蒂姆的方法没有使用这些,所以速度要快得多。但是,如果你坚持使用手动for循环,它的速度是使用Array.findlastedex的两倍,在所有条件相同的情况下

我怀疑Array.findlastedex方法实际上更快,所以我自己测试了它。我借用了Amessichel发布的测试代码,但添加了第三种方法:

Function VarStamm3(name As String) As String
    Dim i As Integer
    For i = name.Length - 1 To 0 Step -1
        If Not Char.IsDigit(name(i)) Then
            Exit For
        End If
    Next i
    Return name.Substring(0, i + 1)
End Function
它使用原始算法,但只是将旧的VB6样式的字符串方法替换为新的.NET等效方法。以下是我机器上的结果:

RunTime :
 - VarStamm : 00:00:07.92
 - VarStamm2 : 00:00:00.60
 - VarStamm3 : 00:00:00.23

正如您所看到的,您的原始算法已经进行了很好的调整。问题不在于循环。问题是Mid、IsNumeric和Len。因为蒂姆的方法没有使用这些,所以速度要快得多。但是,如果您坚持使用手动for循环,它的速度是使用Array.findlastedex的两倍,在所有条件相同的情况下

该函数只返回左边的部分,但这对我来说是可以的,这对我来说似乎非常有效。您可以创建自己的方法,该方法比IsNumeric更有效。通过数组语法(如namei)获取当前字符可能更快。但除了这些小事情,通用算法看起来不错。我最大的抱怨是您使用了传统的VB6风格的函数,如Mid、IsNumeric和Len,而不是更新的.NET等效函数,但我不知道.NET等效函数是否真的会更快。看起来不错,除非你需要处理字符串结尾不是数字的情况,你仍然需要拆分它。函数只返回左边的部分,但这对我来说没关系,看起来对我来说效率很高。您可以创建自己的方法,该方法比IsNumeric更有效。通过数组语法(如namei)获取当前字符可能更快。但除了这些小事情,通用算法看起来不错。我最大的抱怨是您使用了传统的VB6风格的函数,如Mid、IsNumeric和Len,而不是更新的.NET等效函数,但我不知道.NET等效函数是否真的会更快。看起来不错,除非你需要处理字符串结尾不是数字的情况,你仍然需要拆分它。@Amesshiel:比什么慢,为什么?@Amesshiel:你测试了这两个,或者为什么你说它慢?最慢的部分是text.tochararrymy bad,你的代码要快得多。我会发布一个答案来证明这一点。@Amesshiel:如果您想要更快的版本,您需要为String.FindLastIndex创建一个扩展方法,该扩展方法将谓词作为Char、Boolean的FuncOf。然后,您可以向后循环字符串,而无需使用ToCharray,因为ToCharray总是创建一个新字符。这个方法的主体是:For i As Int32=text.Length-1到0步骤-1如果谓词texti那么返回i Next Return-1非常感谢你们!巨大的成功:@Amesshiel:比什么慢?为什么?@Amesshiel:你测试了两者还是说慢?最慢的部分是text.tochararrymy bad,你的代码要快得多。我会发布一个答案来证明这一点。@Amesshiel:如果你想要一个更快的版本,你可以
需要为String.FindLastIndex创建一个扩展方法,该扩展方法将谓词作为Char、Boolean的函数。然后,您可以向后循环字符串,而无需使用ToCharray,因为ToCharray总是创建一个新字符。这个方法的主体是:For i As Int32=text.Length-1到0步骤-1如果谓词texti那么返回i Next Return-1非常感谢你们!巨大的成功:你的怀疑并非完全错误。看我的答案。你的怀疑并不是完全错误的。看我的答案。是的,确实值得一提的是,这个问题与算法无关。听起来您的实现是第一位的。@SteveDoggart计时时,您是否从Tim的解决方案中删除了Dim part2=text.SubstringlastNonDigitIndex?“我不喜欢长的一行,我对速度差感兴趣,如果有的话。”玛丽问得好。我刚刚从Amesshiel的答案中复制了代码,并添加了新方法。看起来,在VarStamm2方法中,他删除了不必要的行,所以这就是我测试的内容。谢谢你,Steve。是的,确实值得一提的是,这个问题与算法无关。听起来您的实现是第一位的。@SteveDoggart计时时,您是否从Tim的解决方案中删除了Dim part2=text.SubstringlastNonDigitIndex?“我不喜欢长的一行,我对速度差感兴趣,如果有的话。”玛丽问得好。我刚刚从Amesshiel的答案中复制了代码,并添加了新方法。看起来,在VarStamm2方法中,他删除了不必要的行,所以这就是我测试的内容。谢谢你,Steve。