如何获取序列中的第一个和最后一个数字
How to get the first and last numbers in a sequence
我正在与 VBA 合作,尝试获取分隔数字序列中的第一个和最后一个数字。
数据仅显示为逗号分隔的数字序列。它们始终按数字升序排列。
所以这方面的一个例子可能是:
1,2,3,5,7,8,9
只需要第一个和最后一个序列,序列定义为比前一个数字多一个数字,在这种情况下有两个序列:
1,2,3
和 7,8,9
。 5 不在序列中,因为它前后相隔不止一个(缺少 4 和 6)。
在这两种情况下,我需要每个序列的第一个和最后一个数字,即第一个序列的 1 & 3
和第二个序列的 7 & 9
。
我想知道正则表达式是否适用于此,或者将它们放入某个集合以便能够更轻松地向后和向前导航是否更好?
真的不确定从哪里开始 - 有什么想法吗?
非常感谢。
最简单的方法可能是使用 Split
:
NumberSequence = "1,2,3,5,7,8,9"
ValueList = Split(NumberSequence, ",")
然后拉取 ValueList 数组中第一个和最后一个索引的值。
问题描述中的复杂之处在于识别数字序列中何时“缺失”数字,但 Split
也有助于解决此问题。将数字读入数组后,很容易遍历它们并确定“差距”在哪里。
这说明了方法:
Sub SampleProject()
GetMinAndMax "1,2,3,5,7,8,9"
End Sub
Sub GetMinAndMax(NumberSequence As String)
ValueList = Split(NumberSequence, ",")
MinValue = CInt(ValueList(0))
For i = 1 To UBound(ValueList)
If CInt(ValueList(i)) > CInt(ValueList(i - 1)) + 1 Then
MaxValue = CInt(ValueList(i - 1))
'Ignore single numbers ("5" in your example)
If Not MinValue = MaxValue Then MsgBox MinValue & " - " & MaxValue
MinValue = CInt(ValueList(i))
ElseIf i = UBound(ValueList) Then
MaxValue = CInt(ValueList(UBound(ValueList)))
MsgBox MinValue & " - " & MaxValue
End If
Next
End Sub
请尝试下一个功能:
Function SequenceMargins(s As String) As Variant
Dim arr As Variant, i As Long, strSeq As String, firstEl As Long
Dim arrFin As Variant, k As Long
arr = Split(s, ",")
ReDim arrFin(UBound(arr))
For i = 0 To UBound(arr) - 1
If CLng(arr(i)) = CLng(arr(i + 1)) - 1 And firstEl = 0 Then firstEl = CLng(arr(i))
If firstEl <> 0 And CLng(arr(i)) > firstEl And CLng(arr(i)) <> CLng(arr(i + 1)) - 1 Then
arrFin(k) = firstEl & "&" & arr(i): k = k + 1
firstEl = 0
End If
If i = UBound(arr) - 1 And firstEl <> 0 Then
arrFin(k) = firstEl & "&" & arr(UBound(arr)): k = k + 1
End If
Next i
ReDim Preserve arrFin(k - 1)
SequenceMargins = arrFin
End Function
可以这样调用:
Sub testSequenceMargins()
Dim s As String, arr As Variant
s = "1,2,3,5,7,8,9,10,13,14,15,20,34,35,36"
arr = SequenceMargins(s)
Debug.Print UBound(arr), arr(0), arr(UBound(arr))
End Sub
此方法采用包含数字序列的数组和 returns 包含找到的每个序列的第一个和最后一个数字的集合:
Option Explicit
Private Sub Form_Load()
Dim c As Collection
Set c = FirstAndLast(Array(1, 2, 3, 5, 7, 8, 9))
End Sub
Public Function FirstAndLast(ByVal Sequence As Variant) As Collection
Dim i As Integer
Set FirstAndLast = New Collection
For i = LBound(Sequence) To UBound(Sequence) - 1
If Sequence(i) + 1 = Sequence(i + 1) Then
If FirstAndLast.Count Mod 2 = 0 Then FirstAndLast.Add Sequence(i)
If i = UBound(Sequence) - 1 Then FirstAndLast.Add Sequence(i + 1)
Else
If FirstAndLast.Count Mod 2 = 1 Then FirstAndLast.Add Sequence(i)
End If
Next
End Function
我正在与 VBA 合作,尝试获取分隔数字序列中的第一个和最后一个数字。
数据仅显示为逗号分隔的数字序列。它们始终按数字升序排列。
所以这方面的一个例子可能是:
1,2,3,5,7,8,9
只需要第一个和最后一个序列,序列定义为比前一个数字多一个数字,在这种情况下有两个序列:
1,2,3
和 7,8,9
。 5 不在序列中,因为它前后相隔不止一个(缺少 4 和 6)。
在这两种情况下,我需要每个序列的第一个和最后一个数字,即第一个序列的 1 & 3
和第二个序列的 7 & 9
。
我想知道正则表达式是否适用于此,或者将它们放入某个集合以便能够更轻松地向后和向前导航是否更好?
真的不确定从哪里开始 - 有什么想法吗?
非常感谢。
最简单的方法可能是使用 Split
:
NumberSequence = "1,2,3,5,7,8,9"
ValueList = Split(NumberSequence, ",")
然后拉取 ValueList 数组中第一个和最后一个索引的值。
问题描述中的复杂之处在于识别数字序列中何时“缺失”数字,但 Split
也有助于解决此问题。将数字读入数组后,很容易遍历它们并确定“差距”在哪里。
这说明了方法:
Sub SampleProject()
GetMinAndMax "1,2,3,5,7,8,9"
End Sub
Sub GetMinAndMax(NumberSequence As String)
ValueList = Split(NumberSequence, ",")
MinValue = CInt(ValueList(0))
For i = 1 To UBound(ValueList)
If CInt(ValueList(i)) > CInt(ValueList(i - 1)) + 1 Then
MaxValue = CInt(ValueList(i - 1))
'Ignore single numbers ("5" in your example)
If Not MinValue = MaxValue Then MsgBox MinValue & " - " & MaxValue
MinValue = CInt(ValueList(i))
ElseIf i = UBound(ValueList) Then
MaxValue = CInt(ValueList(UBound(ValueList)))
MsgBox MinValue & " - " & MaxValue
End If
Next
End Sub
请尝试下一个功能:
Function SequenceMargins(s As String) As Variant
Dim arr As Variant, i As Long, strSeq As String, firstEl As Long
Dim arrFin As Variant, k As Long
arr = Split(s, ",")
ReDim arrFin(UBound(arr))
For i = 0 To UBound(arr) - 1
If CLng(arr(i)) = CLng(arr(i + 1)) - 1 And firstEl = 0 Then firstEl = CLng(arr(i))
If firstEl <> 0 And CLng(arr(i)) > firstEl And CLng(arr(i)) <> CLng(arr(i + 1)) - 1 Then
arrFin(k) = firstEl & "&" & arr(i): k = k + 1
firstEl = 0
End If
If i = UBound(arr) - 1 And firstEl <> 0 Then
arrFin(k) = firstEl & "&" & arr(UBound(arr)): k = k + 1
End If
Next i
ReDim Preserve arrFin(k - 1)
SequenceMargins = arrFin
End Function
可以这样调用:
Sub testSequenceMargins()
Dim s As String, arr As Variant
s = "1,2,3,5,7,8,9,10,13,14,15,20,34,35,36"
arr = SequenceMargins(s)
Debug.Print UBound(arr), arr(0), arr(UBound(arr))
End Sub
此方法采用包含数字序列的数组和 returns 包含找到的每个序列的第一个和最后一个数字的集合:
Option Explicit
Private Sub Form_Load()
Dim c As Collection
Set c = FirstAndLast(Array(1, 2, 3, 5, 7, 8, 9))
End Sub
Public Function FirstAndLast(ByVal Sequence As Variant) As Collection
Dim i As Integer
Set FirstAndLast = New Collection
For i = LBound(Sequence) To UBound(Sequence) - 1
If Sequence(i) + 1 = Sequence(i + 1) Then
If FirstAndLast.Count Mod 2 = 0 Then FirstAndLast.Add Sequence(i)
If i = UBound(Sequence) - 1 Then FirstAndLast.Add Sequence(i + 1)
Else
If FirstAndLast.Count Mod 2 = 1 Then FirstAndLast.Add Sequence(i)
End If
Next
End Function