title: Golang 統計テキスト文字列中の異なる単語の出現頻度を計算し、複数回出現する単語とその頻度を表示する
date: 2022-05-22 15:17:00
toc: false
index_img: https://b3logfile.com/file/2022/05/Snipaste_2022-05-22_15-42-36-a560234d.png
category:
- Go
tags: - Golang
- 出力
- 統計
- テキスト
- 文字列
- 異なる
- 単語
- 出現
- 頻度
- 表示
- 回数
- 頻度
コード#
package main
import (
"fmt"
"sort"
"strings"
)
var s = "Fluff lettuce thoroughly, then mix with tea and serve smoothly in bottle.Enamel half a kilo of strudel in twenty and a half teaspoons of pork butt sauce."
var symbolCollection = []string{
".",
",",
}
func main() {
result := make(map[string]int)
fields := strings.Fields(s)
for _, v := range fields {
newV := strings.ToLower(v)
for _, sym := range symbolCollection {
newV = strings.Trim(newV, sym)
}
val, ok := result[v]
if ok {
val++
result[v] = val
} else {
result[v] = 1
}
}
unique := make([]string, 0, len(result))
for t := range result {
unique = append(unique, t)
}
sort.Strings(unique)
for _, k := range unique {
v := result[k]
if v > 1 {
fmt.Println(k, v)
}
}
}
結果#
a 2
of 2
and 2
in 2
half 2
結論#
strings
パッケージのTrim
、ToLower
、Fields
メソッドの使用方法を復習しました。- マップ(Map)の使用方法を確認しました。
- マップのキーに基づいてソートされた出力を生成する方法を確認しました。
- マップを範囲で反復処理する方法を確認しました。
- マップとスライスは参照渡しです。
要約#
- マップは非構造化データの多目的コレクターです。
- 複合リテラルはマップの初期化に非常に便利な方法です。
- キーワード
range
を使用すると、マップを反復処理できます。 - マップは値が代入されたり関数に渡されたりしても、共有された基礎データを共有します。
- コレクターを組み合わせて使用することで、コレクターのパワーをさらに向上させることができます。
追加情報#
Go 言語にはコレクションコレクターが直接提供されていませんが、マップを使用して一時的なコレクションを作成することができます。コレクションとして使用されるマップでは、キーの値は通常重要ではありませんが、メンバーの関係を確認しやすくするために、キーの値は通常 true に設定されます。
元の回答#
package main
import (
"fmt"
"sort"
"strings"
)
func countWords(text string) map[string]int {
words := strings.Fields(strings.ToLower(text))
frequency := make(map[string]int, len(words))
for _, word := range words {
newWord := strings.Trim(word, `.,`)
frequency[newWord]++
}
return frequency
}
func main() {
var text = "Fluff lettuce thoroughly, then mix with tea and serve smoothly in bottle.Enamel half a kilo of strudel in twenty and a half teaspoons of pork butt sauce."
frequency := countWords(text)
unique := make([]string, 0, len(frequency))
for k := range frequency {
unique = append(unique, k)
}
sort.Strings(unique)
for _, word := range unique {
count := frequency[word]
if count > 1 {
fmt.Printf("%s: %d\n", word, count)
}
}
}
- コードを簡素化するために関数を使用するべきであり、目的を達成するためにコードのエレガントさとパフォーマンスを無視するべきではありません。
- 論理的な考慮が不足しており、ネイティブ関数に精通していないため、単語の取得元は
strings.Fields(strings.ToLower(text))
であるべきであり、まずTrim
を行い、その後配列からループして削除する必要があります。 - マップ内の値は直接変更できます。例:
frequency[newWord]++
のように、val++; result[v] = val
のような操作は必要ありません。