문제

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

그런 다음 빠른 데모 애플리케이션을 위해 inputbox라는 하나의 멀티 라인 텍스트 상자, 하나의 목록 뷰가 outputList 호출 및 countBtn이라는 하나의 버튼이있는 winforms 앱을 만듭니다. 목록보기에서 "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로 이것을 쓰도록 끔찍한 일을했고 나는 결코 당신을 용서하지 않을 것입니다.

:피

행운을 빕니다!

편집하다

빈 문자열 버그 및 케이스 버그를 수정했습니다

다른 팁

이것은 당신이 찾고있는 것일 수 있습니다.

    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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top