Допустим, у меня есть строка, которая различается по размеру и имеет значение «OOOO». Мне нужно, чтобы приведенный ниже код также возвращал «O0O0, 0O0O, 0OO0, O00O, O000, OO00, OOO0». В основном все возможные варианты O заменены на 0. Как лучше всего это сделать? В настоящее время он возвращает только «0OOO, 00OO, 000O, 0000».
Public Function ParseOs(ByVal PlayerName As String) As String()
Dim NameChar As Char
Dim OCount As Integer
Dim OCountTwo As Integer
For i = 0 To PlayerName.Length - 1
NameChar = PlayerName.Chars(i)
If NameChar = "O" Then
OCount += 1
End If
Next
Dim NewPlayerName() As String = New String(OCount - 1) {}
For y = 0 To PlayerName.Length - 1
NameChar = PlayerName.Chars(y)
If NameChar = "O" Then
NewPlayerName(OCountTwo) = PlayerName.Remove(y, 1).Insert(y, "0")
PlayerName = NewPlayerName(OCountTwo)
OCountTwo += 1
End If
Next
Return NewPlayerName
End Function
Длина вашего массива NewPlayerName неверна, она будет равна 2^OCount. Поскольку есть только 2 возможных символа, это похоже на двоичный счет.
Один из способов сделать это через рекурсию:
Public Iterator Function ParseOs(ByVal PlayerName As String) As IEnumerable(Of String)
Dim i as Integer = PlayerName.IndexOf("O")
If i = -1 Then
Yield Return PlayerName
Yield Break
End If
'Keep everything (if anything) *before* the O
Dim base As String = PlayerName.SubString(0, i)
Dim permutations As IEnumerable(Of String) = New String() {""}
If PlayerName.Length > i Then
'Recurse to find all the variations for everything *after* the O
permutations = ParseOs(PlayerName.SubString(i+1))
End If
For Each permutation As String in permutations
Yield Return base & "O" & permutation
Yield Return base & "0" & permutation
Next
End Function
Если вы Конечно, все входы всегда будут равны нулю, вы можете еще больше упростить:
Public Iterator Function ParseOs(ByVal PlayerName As String) As IEnumerable(Of String)
Dim permutations As IEnumerable(Of String) = New String() {""}
If PlayerName.Length > 1 Then
permutations = ParseOs(PlayerName.SubString(1))
End If
For Each permutation As String in permutations
Yield Return "O" & permutation
Yield Return "0" & permutation
Next
End Function
Вы можете сделать их более эффективными, разбив их на две функции, где рекурсивная часть работает с массивами символов, а не со строками. Затем вы можете сделать это более эффективным, преобразовав массивы для использования Span<Char>
, чтобы вам не приходилось выделять новый массив для каждого рекурсивного вызова.
На входе будут другие символы, которые не являются Os, поэтому первое опубликованное вами решение работает именно так, как мне нужно. Например, "TODOORNOTTODO" может быть вводом.
То, что вы хотите сделать, это генерировать перестановки. Это для C#, но эта статья может помочь. ericlippert.com/2013/04/15/производство-перестановок-часть-один Все начинается иначе, чем то, что вы делаете, но закладывает концептуальную основу и в конечном итоге доходит до мельчайших деталей реализации.