どうも!リョクちゃです。
今回は、あるテキストファイル内に含まれる単語の数をカウントし、
どの単語が一番多く含まれているかを判定してくれるプログラムを
作っていくうえでの考え方や実際に作ったのでコードなどを紹介していきます。
カウントする上で以前にも紹介したDictionaryを使って行うことで更なる使い方を
覚えてもらえたらなって思います。
ちなみに前回はこちら。
目次
準備編
準備編:フォームの作成
以下のフォームを作成していきます。
各①~⑤のコントロールについては、以下の表になります。
No | アイテム | コントロール名 |
---|---|---|
1 | Label | Label1 |
2 | Label | Label2 |
3 | TextBox | TextBox1 |
4 | TextBox | TextBox2 |
5 | Button | Button1 |
準備編:テキストファイルの準備
単語の数をカウントするにあたって、以下のテキストファイルを準備します。
上図のような、テキストファイルを作成しデスクトップ上に保存しておきます。
実行環境
筆者の実行環境は、
- VisualStudio2019
- Windows 10 64bit
- .Net Framework 4.5.1
になります。
※ Windows7 8 8.1でも動作はできますが、画面デザインの表示が変わるかもしれません。
アプリケーションの目的
ボタンを押すことでファイルダイアログが開き、適当なテキストファイルを読込ませることで
そのテキストファイル内に含まれる単語の数をカウントし、テキストファイルに含まれる
単語の中で最も多く出現する単語と数を表示することを目的とします。
プログラム編
定数・変数の宣言
単語の数を格納する変数を用意しておきます。
1 2 3 4 |
''' <summary> ''' 単語の数を格納する変数 ''' </summary> Private dictWord As Dictionary(Of String, Integer) |
処理するファイルを選択する処理
ファイルダイアログをボタンが押されたときに実行できるよう実装します。
ファイルダイアログに関しては、以下の記事をご参照ください。
簡単にまとめています。
読込むファイルは今回は.txtのみを想定しております。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
''' <summary> ''' テキストファイル読込みボタン押下 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' ファイルダイアログを開く変数を作成しインスタンス化 Dim testFileDialog As New OpenFileDialog() ' 各パラメータを設定していきます ' 最初に表示されるデフォルトのファイル名を設定 testFileDialog.FileName = "default.txt" ' 最初に表示されるデフォルトのフォルダ名を設定 testFileDialog.InitialDirectory = "C:/" ' 読込むファイルの種類を設定 testFileDialog.Filter = "テキスト文書" & "|" & "*.txt" ' ファイルダイアログのタイトルを設定 testFileDialog.Title = "読込みたいファイルを選択してください。" ' ファイルダイアログを閉じる前に現在のフォルダを復元するかしないか testFileDialog.RestoreDirectory = True ' ファイルダイアログを開く ' 読込みたいファイルを選択し、OKボタンが押されたら If testFileDialog.ShowDialog() = DialogResult.OK Then ' 出力ウィンドウ(VisualStudio)に選択されたファイル名を表示 Console.WriteLine(testFileDialog.FileName) ' ファイルが選択されていない場合を考慮して If testFileDialog.FileName <> "" Then ' 単語の個数をカウントする処理をここに書きます。 End If End If End Sub |
単語をカウントする関数を作成
戻り値として、単語のカウント結果をDictionary変数で返す関数を作成していきます。
流れとしては、
- 読込むファイルのパスを引数として渡します。
- 1で渡された引数のファイルを読込みます。
- 戻り値として返すDictionary変数を新たに宣言しておきます。
- 1行ずつ読み込んでいきます。
- 1行内に複数の単語がある場合を想定して、Splitメソッドで分割します。
- 単語ごとに宣言したDictionary変数に単語をキーに値を個数にして代入します。
この時、既にDictionaryにある場合は個数をインクリメントします。
実際に関数の部分は、3~6になります。
これをコードで書くと、以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
''' <summary> ''' テキストファイル内の単語の数をカウントし、結果を返す関数 ''' </summary> ''' <param name="filePath">読込みたいファイルのパス</param> ''' <returns></returns> Private Function GetWordCount(ByVal filePath As String) As Dictionary(Of String, Integer) ' 1で渡された引数のファイルを読込みます。 Dim sr As New System.IO.StreamReader(filePath) ' 戻り値として返すDictionary変数を新たに宣言しておきます。 Dim dictResult As Dictionary(Of String, Integer) = New Dictionary(Of String, Integer) ' 1行ずつ読み込んでいきます。 While sr.Peek >= 0 ' 1行内に複数の単語がある場合を想定して、Splitメソッドで分割します。 Dim line() As String = sr.ReadLine.Split() For Each word As String In line ' 単語ごとに宣言したDictionary変数に単語をキーに値を個数にして代入します。 If dictResult.ContainsKey(word) Then ' 既にDictionaryにある場合は個数をインクリメントします。 dictResult(word) += 1 Else ' Dictionaryに存在しないなら1を代入 dictResult(word) = 1 End If Next word End While ' ファイル処理解放 sr.Close() sr.Dispose() sr = Nothing GC.Collect() ' 戻り値を返す Return dictResult End Function |
作成した関数をファイルが選択されてからの処理の箇所に記述していきます。
1 2 3 |
' ファイル内の単語の出現個数をカウント ' 単語の数を格納する変数に作成した関数の結果を代入します。 dictWord = GetWordCount(testFileDialog.FileName) |
一番多く含まれている単語と個数を表示
dictWordに格納された単語と個数のペアから、
最大個数の単語を各テキストボックスに表示をします。
dictWordから最大個数を見つけるには、Maxメソッドを使用します。
今回は、個数の最大値を対象に、Maxメソッドを使います。
これを使って、以下のように処理を書きます。
1 2 3 4 5 6 |
For Each dictTemp As KeyValuePair(Of String, Integer) In dictWord If dictWord.Values.Max() = dictTemp.Value Then ' 最大個数 textRec = textRec + " " + dictTemp.Key End If Next dictTemp |
Forループで最大個数のキーを変数textRecに代入していきます。
最後に、変数textRecと最大個数の値を各テキストボックスに表示をしていきます。
1 2 |
Me.TextBox1.Text = textRec ' 最大個数のキーをテキストボックスに表示 Me.TextBox2.Text = dictWord.Values.Max() ' 最大個数をテキストボックスに表示 |
全体コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
Public Class WordCount ''' <summary> ''' 単語の数を格納する変数 ''' </summary> Private dictWord As Dictionary(Of String, Integer) ''' <summary> ''' テキストファイル内の単語の数をカウントし、結果を返す関数 ''' </summary> ''' <param name="filePath">読込みたいファイルのパス</param> ''' <returns></returns> Private Function GetWordCount(ByVal filePath As String) As Dictionary(Of String, Integer) ' 1で渡された引数のファイルを読込みます。 Dim sr As New System.IO.StreamReader(filePath) ' 戻り値として返すDictionary変数を新たに宣言しておきます。 Dim dictResult As Dictionary(Of String, Integer) = New Dictionary(Of String, Integer) ' 1行ずつ読み込んでいきます。 While sr.Peek >= 0 ' 1行内に複数の単語がある場合を想定して、Splitメソッドで分割します。 Dim line() As String = sr.ReadLine.Split() For Each word As String In line ' 単語ごとに宣言したDictionary変数に単語をキーに値を個数にして代入します。 If dictResult.ContainsKey(word) Then ' 既にDictionaryにある場合は個数をインクリメントします。 dictResult(word) += 1 Else ' Dictionaryに存在しないなら1を代入 dictResult(word) = 1 End If Next word End While ' ファイル処理解放 sr.Close() sr.Dispose() sr = Nothing GC.Collect() ' 戻り値を返す Return dictResult End Function ''' <summary> ''' テキストファイル読込みボタン押下 ''' </summary> ''' <param name="sender"></param> ''' <param name="e"></param> Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ' ファイルダイアログを開く変数を作成しインスタンス化 Dim testFileDialog As New OpenFileDialog() ' 各パラメータを設定していきます ' 最初に表示されるデフォルトのファイル名を設定 testFileDialog.FileName = "default.txt" ' 最初に表示されるデフォルトのフォルダ名を設定 testFileDialog.InitialDirectory = "C:/" ' 読込むファイルの種類を設定 testFileDialog.Filter = "テキスト文書" & "|" & "*.txt" & "|" & "CSVファイル" & "|" & "*.csv" ' ファイルダイアログのタイトルを設定 testFileDialog.Title = "読込みたいファイルを選択してください。" ' ファイルダイアログを閉じる前に現在のフォルダを復元するかしないか testFileDialog.RestoreDirectory = True ' ファイルダイアログを開く ' 読込みたいファイルを選択し、OKボタンが押されたら If testFileDialog.ShowDialog() = DialogResult.OK Then ' 出力ウィンドウ(VisualStudio)に選択されたファイル名を表示 Console.WriteLine(testFileDialog.FileName) ' ファイルが選択されていない場合を考慮して If testFileDialog.FileName <> "" Then ' ファイル内の単語の出現個数をカウント dictWord = GetWordCount(testFileDialog.FileName) ' 一番多い単語と個数をラベルに表示 Dim textRec As String = "" For Each dictTemp As KeyValuePair(Of String, Integer) In dictWord If dictWord.Values.Max() = dictTemp.Value Then ' 最大個数のキーを代入 textRec = textRec + " " + dictTemp.Key End If Next dictTemp Me.TextBox1.Text = textRec ' 最大個数のキーをテキストボックスに表示 Me.TextBox2.Text = dictWord.Values.Max() ' 最大個数をテキストボックスに表示 End If End If End Sub End Class |
実行編
作成したコードを実行していきます。
プログラム起動時の画面
テキストファイルを読込みボタン押下時
選択したテキストファイル内の単語カウント結果反映時
まとめ
あるテキストファイル内の単語をカウントし、一番多い単語の数と単語を表示する方法をDictionaryを使って解説しました。
単語やモノの数をカウントする際にDictionaryは非常に有用性のある型です。
こうした使い方もあるんだとイメージを抱いていただけたら嬉しいです。
実際にこういった処理を書く必要なケースに出くわした場合、
思い出してもらえたらなと思います。
・こちらの書籍を参考にVB.Net勉強しています。