我编写的代码允许用户输入一个句子,然后搜索某个单词的位置。我现在如何调整它以便在输入句子时,程序然后输出每个单词在第一次出现时的位置?
Module Module1
Sub Main()
Dim WordNumber As Integer = 0
Dim StartofWord As Integer = 1
Dim Text As String = ""
Dim L As Integer = 0
Dim Word As String
Console.WriteLine("Enter your sentence ")
Dim LotsofText As String = UCase(Console.ReadLine)
Console.WriteLine("Enter your word")
Word = UCase(Console.ReadLine())
'LotsofText= Console.ReadLine + " "
If Mid(LotsofText, Len(LotsofText) - 1, 1) <> " " Then LotsofText = LotsofText + " "
For L = 1 To LotsofText.Length
If (Mid(LotsofText, L, 1)) = " " Then
WordNumber = WordNumber + 1
Text = (Mid(LotsofText, StartofWord, L - StartofWord))
'Console.WriteLine(Text)
StartofWord = L + 1
If Text = Word Then
Console.WriteLine(WordNumber)
End If
End If
Next
If Not Text = Word Then
Console.WriteLine("Error word not found")
End If
Console.Write("Press Enter to Exit")
Console.ReadLine()
End Sub
End Module
答案 0 :(得分:1)
没有板载方法,并不是很简单。一种方法是迭代每个字符并查看是否是空格。如果你找到了一个,你需要找到单词的开头,因为可能有连续的空格。一旦你有了这个索引,你需要寻找下一个空格,因为那是单词的结尾。如果这个单词等于您正在搜索的单词,则您拥有索引。
因为编写一个可以重复使用的方法非常困难,例如,如果你想找到所有匹配索引或者最后一个。因此,您可以使用同时也存在于VB.NET中的迭代器。他们允许懒洋洋地返回东西,所以只有你要求它们。如果你要求第一个方法,一旦返回第一个方法就会中断:
Public Shared Iterator Function GetIndexesOfWord(input As String, wordToFind As String, Optional comparer As StringComparer = Nothing, Optional wordSeparator As Char = " "c) As IEnumerable(Of Int32)
If comparer Is Nothing Then comparer = StringComparer.Ordinal
For index As Int32 = 0 To input.Length - 1
If index = 0 OrElse input(index) = wordSeparator Then
Dim token = input.Substring(index)
Dim trimmed = token.TrimStart(wordSeparator)
index = index + (token.Length - trimmed.Length) ' start of word
Dim endIndex = input.IndexOf(wordSeparator, index)
If endIndex = -1 Then endIndex = input.Length
Dim length = endIndex - index
Dim word = input.Substring(index, length)
If comparer.Equals(word, wordToFind) Then
Yield index
End If
index = endIndex - 1 ' -1 because the for-loop will jump over the space otherwise
End If
Next
End Function
以下是一个例子:
Dim sentence = "this is just sample text that contains a text sample"
Dim word = "sample"
Dim indexes = GetIndexesOfWord(sentence, word)
如果您只想要第一个索引:
Dim firstIndex As Int32 = indexes.First()
如果你想要所有,你可以填写一个集合,例如:
Dim indexList As List(Of Int32) = indexes.ToList()
如果您使用该列表,则可以检查lict.Count > 0
,并且您知道该单词是否在句子中。如果您使用First
,Last
或其他返回单个索引的方法,则可能会获得InvalidOperationException
。在这种情况下,FirstOrdefault
没有帮助,因为Int32
的默认值为0,这是一个有效的索引。因此,您可以使用此方法来确定是否存在匹配,以及是否有一个获得第一个索引:
Dim firstIndex As Int32 = indexes.DefaultIfEmpty(-1).First()
现在您知道-1表示该单词不在该句子中。
由于您使用的是Visual Studio 2010,因此您无法在VB.NET中使用延迟执行迭代器和Yield
语句。你要么必须返回第一个找到的索引,如果你只需要第一个索引就是有效的。或者您使用此方法填充包含所有索引的列表:
Public Shared Function GetIndexesOfWord(input As String, wordToFind As String, Optional comparer As StringComparer = Nothing, Optional wordSeparator As Char = " "c) As IEnumerable(Of Int32)
If comparer Is Nothing Then comparer = StringComparer.Ordinal
Dim allIndexes = new List(Of Int32)
For index As Int32 = 0 To input.Length - 1
If index = 0 OrElse input(index) = wordSeparator Then
Dim token = input.Substring(index)
Dim trimmed = token.TrimStart(wordSeparator)
index = index + (token.Length - trimmed.Length) ' start of word
Dim endIndex = input.IndexOf(wordSeparator, index)
If endIndex = -1 Then endIndex = input.Length
Dim length = endIndex - index
Dim word = input.Substring(index, length)
If comparer.Equals(word, wordToFind) Then
allIndexes.Add(index)
End If
index = endIndex - 1 ' -1 because the for-loop will jump over the space otherwise
End If
Next
return allIndexes
End Function