VB.NETで単語の頻度を計算する最良の方法は何ですか?
-
03-07-2019 - |
質問
C#で単語の頻度を計算する方法には良い例がいくつかありますが、どれも包括的ではなく、VB.NETで実際に必要です。
現在のアプローチは、周波数カウントごとに1ワードに制限されています。完全に正確な単語頻度リストを取得できるようにこれを変更する最良の方法は何ですか?
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
クイックデモアプリケーションの場合、InputBoxという複数行のテキストボックス、OutputListという1つのリストビュー、CountBtnという1つのボタンを含むwinformsアプリを作成します。リストビューで2つの列を作成します-&quot; Word&quot;および "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()
テストを行ったところ、動作します
編集!記号ではなく文字のみをカウントするようにコードを追加しました。
FYI:LINQとターゲット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
これは役に立つかもしれません: