回顾:词频计数器
本课属于 Coddy GO 学习旅程的“逻辑与流程”单元。第 30 课,共 68 课。
挑战
简单构建一个文本分析工具,用于统计文档中的词频。本挑战将展示映射如何通过记录文本中每个不同单词出现的次数,高效地汇总数据。
你会收到两个输入:
- 一个表示待分析文本的字符串(例如:
"the quick brown fox jumps over the lazy dog the fox is quick") - 一个表示最低频率阈值的字符串(例如:
"2")
重要:输入文本可能包含空格,因此你必须使用 bufio.NewReader 和 ReadString('\n'),或使用 bufio.Scanner 读取整行:读取文本输入时不要使用 fmt.Scanln,因为它会在遇到第一个空格时停止读取。
你的任务是:
- 创建一个名为
countWords的函数,该函数接收一个文本字符串,并返回一个map[string]int,其中:- 键是单个单词(字符串)
- 值是每个单词出现的次数(整数)
- 使用
strings.Fields将输入文本拆分成单个单词来解析文本(该函数会按任意空白字符拆分) - 统计文本中每个单词的出现次数:
- 将所有单词转换为小写,以便统一统计
- 对每个单词,将它在映射中的计数加 1
- 如果映射中还没有某个单词,它的初始值会是 0,然后计数会加到 1
- 筛选结果,只显示出现次数至少达到阈值的单词
- 按以下格式显示结果:
- 标题:
"Word Frequency Analysis:" - 每个符合条件的单词:
"[word]: [count]" - 按字母顺序显示单词
- 标题:
- 计算并显示统计摘要:
"Total unique words: [total_unique_count]""Words above threshold: [filtered_count]""Most frequent word: [word] ([count] times)"- 如果多个单词的最高计数相同,就报告按字母顺序排在最前面的单词。如果每个单词都只出现一次,那就是排序后列表中的第一个单词。
例如,输入文本为 "hello hello world",阈值为 "2" 时,输出应为:
Word Frequency Analysis: hello: 2 Total unique words: 2 Words above threshold: 1 Most frequent word: hello (2 times)
使用 bufio 包读取完整的输入行,使用 strings 包拆分文本并转换为小写,使用 strconv 包将阈值字符串转换为整数,并使用 sort 包按字母顺序排列单词。本挑战将展示映射如何优雅地解决计数和数据汇总问题。映射的零值特性让计数逻辑简单而高效。
亲手试试
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// 读取整行文本(包括空格)
scanner.Scan()
text := scanner.Text()
// 读取阈值
scanner.Scan()
thresholdStr := scanner.Text()
// 将 threshold 转换为整数
threshold, _ := strconv.Atoi(thresholdStr)
// TODO:在下方编写你的代码
// 1. 创建返回 map[string]int 的 countWords 函数
// 提示:使用 strings.Fields 和 strings.ToLower 拆分单词并统一大小写
// 2. 使用该函数统计词频
// 3. 筛选出至少出现 'threshold' 次的单词
// 4. 将筛选出的单词按字母顺序排序并显示
// 5. 计算并显示汇总统计数据
_ = text
_ = threshold
fmt.Println("Word Frequency Analysis:")
}逻辑与流程中的所有课
自己练习: Go 在线编译器