Каков наилучший способ рассчитать частоту слов в VB.NET?
-
03-07-2019 - |
Вопрос
Есть несколько хороших примеров того, как вычислять частоты слов в C #, но ни один из них не является исчерпывающим, и мне действительно нужен один в VB.NET.
Мой текущий подход ограничен одним словом на количество частот.Каков наилучший способ изменить это, чтобы я мог получить полностью точный список частот слов?
wordFreq = New Hashtable()
Dim words As String() = Regex.Split(inputText, "(\W)")
For i As Integer = 0 To words.Length - 1
If words(i) <> "" Then
Dim realWord As Boolean = True
For j As Integer = 0 To words(i).Length - 1
If Char.IsLetter(words(i).Chars(j)) = False Then
realWord = False
End If
Next j
If realWord = True Then
If wordFreq.Contains(words(i).ToLower()) Then
wordFreq(words(i).ToLower()) += 1
Else
wordFreq.Add(words(i).ToLower, 1)
End If
End If
End If
Next
Me.wordCount = New SortedList
For Each de As DictionaryEntry In wordFreq
If wordCount.ContainsKey(de.Value) = False Then
wordCount.Add(de.Value, de.Key)
End If
Next
Я бы предпочел реальный фрагмент кода, но общее "о да ... используй это и запусти это" тоже сработало бы.
Решение
Public Class CountWords
Public Function WordCount(ByVal str As String) As Dictionary(Of String, Integer)
Dim ret As Dictionary(Of String, Integer) = New Dictionary(Of String, Integer)
Dim word As String = ""
Dim add As Boolean = True
Dim ch As Char
str = str.ToLower
For index As Integer = 1 To str.Length - 1 Step index + 1
ch = str(index)
If Char.IsLetter(ch) Then
add = True
word += ch
ElseIf add And word.Length Then
If Not ret.ContainsKey(word) Then
ret(word) = 1
Else
ret(word) += 1
End If
word = ""
End If
Next
Return ret
End Function
End Class
Затем для быстрой демонстрации приложения создайте приложение winforms с одним многострочным текстовым полем под названием InputBox, одним listview под названием OutputList и одной кнопкой под названием CountBtn .В представлении списка создайте две колонки - "Word" и "Freq". Выберите тип списка "сведения".Добавьте обработчик событий для CountBtn.Затем используйте этот код:
Imports System.Windows.Forms.ListViewItem
Public Class MainForm
Private WordCounts As CountWords = New CountWords
Private Sub CountBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CountBtn.Click
OutputList.Items.Clear()
Dim ret As Dictionary(Of String, Integer) = Me.WordCounts.WordCount(InputBox.Text)
For Each item As String In ret.Keys
Dim litem As ListViewItem = New ListViewItem
litem.Text = item
Dim csitem As ListViewSubItem = New ListViewSubItem(litem, ret.Item(item).ToString())
litem.SubItems.Add(csitem)
OutputList.Items.Add(litem)
Word.Width = -1
Freq.Width = -1
Next
End Sub
End Class
Ты сделал ужасную вещь, заставив меня написать это в VB, и я никогда тебе этого не прощу.
:p
Удачи вам!
Редактировать
Исправлена ошибка с пустой строкой и регистром
Другие советы
Возможно, это то, что вы ищете:
Dim Words = "Hello World ))))) This is a test Hello World"
Dim CountTheWords = From str In Words.Split(" ") _
Where Char.IsLetter(str) _
Group By str Into Count()
Я только что протестировал это, и это действительно работает
РЕДАКТИРОВАТЬ!Я добавил код, чтобы убедиться, что он учитывает только буквы, а не символы.
К ТВОЕМУ сведению:Я нашел статью о том, как использовать LINQ и target 2.0, она кажется немного грязной, но это может кому-то помочь http://weblogs.asp.net/fmarguerie/archive/2007/09/05/linq-support-on-net-2-0.aspx
Довольно близко, но \ w + - это хорошее регулярное выражение для сопоставления (соответствует только символам слова). Р>
Public Function CountWords(ByVal inputText as String) As Dictionary(Of String, Integer)
Dim frequency As New Dictionary(Of String, Integer)
For Each wordMatch as Match in Regex.Match(inputText, "\w+")
If frequency.ContainsKey(wordMatch.Value.ToLower()) Then
frequency(wordMatch.Value.ToLower()) += 1
Else
frequency.Add(wordMatch.Value.ToLower(), 1)
End If
Next
Return frequency
End Function
Это может быть полезно: