我需要删除字符串末尾的数字部分。以下是一些示例:
"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
方法,但是当我需要字符串中最后一个连接数字的索引时,我不知道如何使用它。
答案 0 :(得分:3)
您可以先使用Array.FindLastIndex
,然后再使用Substring
:
Dim lastNonDigitIndex = Array.FindLastIndex(text.ToCharArray(), Function(c) Not char.IsDigit(c))
If lastNonDigitIndex >= 0
lastNonDigitIndex += 1
Dim part1 = text.Substring(0, lastNonDigitIndex)
Dim part2 = text.Substring(lastNonDigitIndex)
End If
答案 1 :(得分:2)
鉴于您的函数VarStamm
和Tim Schmelter的函数VarStamm2
,这是我编写的一个小测试性能。我键入了一个任意的长字符串,该字符串的右部很大,并运行了100万次。
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
这是我得到的输出:
RunTime :
- VarStamm : 00:00:38.33
- VarStamm2 : 00:00:02.72
是的,您应该选择他的答案,他的代码既漂亮又高效。
答案 2 :(得分:2)
我对Array.FindLastIndex
方法实际上更快表示怀疑,因此我自己进行了测试。我借用了Amessihel发布的测试代码,但添加了第三种方法:
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
。由于Tim的方法不使用这些方法,因此速度更快。但是,如果您坚持使用手动for循环,那么在所有条件都相同的情况下,它的速度是使用Array.FindLastIndex
的两倍