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.

È stato utile?

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top