Qual è il modo migliore per calcolare la frequenza delle parole in VB.NET?
-
03-07-2019 - |
Domanda
Ci sono alcuni buoni esempi su come calcolare le frequenze delle parole in C #, ma nessuna di esse è completa e ne ho davvero bisogno in VB.NET.
Il mio approccio attuale è limitato a una parola per conteggio di frequenza. Qual è il modo migliore per cambiare questo in modo da poter ottenere un elenco di frequenza delle parole completamente accurato?
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
Preferirei un vero frammento di codice, ma il generico "oh yeah ... usalo ed eseguilo" funzionerebbe pure.
Soluzione
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
Quindi per un'applicazione demo rapida, crea un'app winforms con una casella di testo multilinea chiamata InputBox, una visualizzazione elenco chiamata OutputList e un pulsante chiamato CountBtn. Nella visualizzazione elenco crea due colonne - " Word " e "Freq." Seleziona " dettagli " tipo di elenco. Aggiungi un gestore eventi per CountBtn. Quindi utilizzare questo codice:
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
Hai fatto una cosa terribile e terribile per farmi scrivere questo in VB e non ti perdonerò mai.
: p
Buona fortuna!
Modifica
Corretto bug stringa vuota e bug case
Altri suggerimenti
Questo potrebbe essere quello che stai cercando:
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()
L'ho appena provato e funziona
EDIT! Ho aggiunto un codice per assicurarmi che conti solo lettere e non simboli.
Cordiali saluti: ho trovato un articolo su come usare LINQ e target 2.0, è un po 'sporco ma potrebbe aiutare qualcuno http://weblogs.asp.net/fmarguerie/archive/2007/09/05/linq-support-on- net-2-0.aspx
Abbastanza vicino, ma \ w + è una buona regex con cui abbinare (corrisponde solo ai caratteri di parole).
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
Questo potrebbe essere utile:
Algoritmo di frequenza delle parole per l'elaborazione del linguaggio naturale