標題:Golang 統計文本字符串中不同單詞的出現頻率並打印不止一次的單詞及詞頻
日期: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
類別:
- Go
標籤: - 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 對映射迭代
- 映射和切片都是引用傳遞
小結#
- 映射是非結構化數據的多用途收集器
- 複合字面量是初始化映射的一種非常方便的手段
- 使用關鍵字 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