Menu
CoddyTech

回顾:词频计数器

本课属于 Coddy GO 学习旅程的“逻辑与流程”单元。第 30 课,共 68 课。

challenge icon

挑战

简单

构建一个文本分析工具,用于统计文档中的词频。本挑战将展示映射如何通过记录文本中每个不同单词出现的次数,高效地汇总数据。

你会收到两个输入:

  • 一个表示待分析文本的字符串(例如:"the quick brown fox jumps over the lazy dog the fox is quick")
  • 一个表示最低频率阈值的字符串(例如:"2")

重要:输入文本可能包含空格,因此你必须使用 bufio.NewReader 和 ReadString('\n'),或使用 bufio.Scanner 读取整行:读取文本输入时不要使用 fmt.Scanln,因为它会在遇到第一个空格时停止读取。

你的任务是:

  1. 创建一个名为 countWords 的函数,该函数接收一个文本字符串,并返回一个 map[string]int,其中:
    • 键是单个单词(字符串)
    • 值是每个单词出现的次数(整数)
  2. 使用 strings.Fields 将输入文本拆分成单个单词来解析文本(该函数会按任意空白字符拆分)
  3. 统计文本中每个单词的出现次数:
    • 将所有单词转换为小写,以便统一统计
    • 对每个单词,将它在映射中的计数加 1
    • 如果映射中还没有某个单词,它的初始值会是 0,然后计数会加到 1
  4. 筛选结果,只显示出现次数至少达到阈值的单词
  5. 按以下格式显示结果:
    • 标题:"Word Frequency Analysis:"
    • 每个符合条件的单词:"[word]: [count]"
    • 按字母顺序显示单词
  6. 计算并显示统计摘要:
    • "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 在线编译器