延續上一篇Split的弔詭這問題,我個人猜測Split可能是用遞迴的方式產生的,所以就很無聊的想要寫一個可以模擬這種程序的範例出來。
延續上一篇Split的弔詭這問題,我個人猜測Split可能是用遞迴的方式產生的,所以就很無聊的想要寫一個可以模擬這種程序的範例出來。
在整個思考過程中我發現其實只有兩條規則,就是如果分隔字元如果位於當前處理字串的開頭則在輸出的陣列中加入一個String.Empty元素;而分隔字元為整個來源字串的最後一個字元也在輸出陣列中加入一個String.Empty元素。而為了證明這個想法的正確性,所以就寫了這個小小的函式。
先解釋一下上一段的當前處理字串,由於在遞迴處理過程中會將已分離的字串從來源字串中移除再繼續呼叫遞迴函式,所以當前處理字串會越來越短直到其長度為零時則跳離遞迴函式。舉個例子來說,當來源為 123x45 且分隔字元為 x 時,第一次進入遞迴後將會把 123 加入結果的List中,且將 123x 從字串中移除,再將 45 做為當前處理字串繼續傳入遞迴函式中處理。
為了不讓整個程式太過複雜,所以這個方法有個限制是只能用一個字元(Char)當做分隔字元,完整的方法內容如下:
(1) 這一段是其它方法要呼叫模擬Split時的方法,而由這個方法中再去呼叫InnerSplit遞迴函式來處理切割字串的程序,另外這一段有兩個地方是
(a) 負責將遞迴中取得的List(Of String)轉回String型別陣列
(b) 先檢查來源字串的最後一個字元是否等於分隔字元並予以標記,使得在傳回結果之前能將最後一個String.Empty加入至List(Of String)
Dim IsLastCharSplitChar As Boolean
If InputString.LastIndexOf(SplitChar) = InputString.Length - 1 Then
IsLastCharSplitChar = True
End If
Dim ResultList As New List(Of String)
InnerSplit(InputString, SplitChar, ResultList)
If IsLastCharSplitChar = True Then
ResultList.Add(String.Empty)
End If
Return ResultList.ToArray()
End Function
(2) 這一段遞迴就是在處理分割字串與移除
Private Sub InnerSplit(ByRef InputString As String, ByVal SplitChar As Char, ByRef ResultList As List(Of String))
If InputString.Length > 0 Then
Dim iIndex As Integer = InputString.IndexOf(SplitChar)
If iIndex >= 0 Then
If iIndex = 0 Then
'當分隔字元位在字串的第一個字元, 則加入String.Empty到List
'並將此字元從字串中移除
ResultList.Add(String.Empty)
InputString = InputString.Remove(0, 1)
Else
'當分隔字元不是字串的第一個字元, 則加入此分隔字元前的字串至List
'並將此字元與其前方字串從字串中移除
ResultList.Add(InputString.Substring(0, iIndex))
InputString = InputString.Remove(0, iIndex + 1)
End If
InnerSplit(InputString, SplitChar, ResultList)
Else
'當找不到分隔字元則將整個字串加入List中
ResultList.Add(InputString)
InputString = InputString.Remove(0, InputString.Length)
End If
End If
End Sub
這邊提供完整的範例程式碼下載(使用Visual Studio 2010)以供玩耍,
主要程式中有使用String.Split方法來對照結果,SplitSimulator02.zip