玩出新花样,给你5个Go语言词频统计扩展练习

简介: 玩出新花样,给你5个Go语言词频统计扩展练习

/ Go 语言词频统计实现 /

词频统计可以分析一段文本中各个词出现的频率,它有许多实用的应用场景,如关键词提取、语言分析等。本文我们将使用 Go 语言实现一个简单的词频统计程序。

主要内容包括:

  1. 问题简述
  2. 初级实现
  3. 分词函数
  4. 数据存储
  5. 统计与输出
  6. 主函数逻辑
  7. 程序测试
  8. 优化思考
  9. 扩展练习

代码示例会包含详细的注释,解释每一段逻辑的具体功能。希望通过详细的实例,可以加深对 Go 语言编程的理解,以及处理文本统计问题的方法。

1

 

1. 问题简述

要求实现一个简单的词频统计程序,功能如下:

  1. 输入一段文本
  2. 对文本进行分词
  3. 统计每个词出现的次数
  4. 按词频输出结果

2

 

2. 初级实现

首先,我们可以使用 map 实现一个简单的单词计数:

// 声明一个map记录词频
frequencies := make(map[string]int) 
// 输入的文本 
input := "hello world hello golang"
// 对空格分割文本  
words := strings.Split(input, " ")
// 统计每个词出现频次
for _, word := range words {
  frequencies[word]++
}
// 输出结果 
fmt.Println(frequencies)

这实现了基本的词频统计和输出要求。

3

 

3. 分词函数

我们可以将文本分词提取封装成一个函数:

// 将文本进行分词
func tokenize(text string) []string {
  return strings.Split(text, " ")
}
words := tokenize(input)

这样可以重用分词逻辑。

我们也可以加强对文本的清理处理,比如转换为小写,移除标点等:

func tokenize(text string) []string {
  // 转小写
  text = strings.ToLower(text)
  // 移除标点
  regex, _ := regexp.Compile("[^a-zA-Z]+") 
  text = regex.ReplaceAllString(text, "")
  // 分词
  return strings.Split(text, " ")
}

4

 

4. 数据存储

使用 map 可以灵活统计词频,我们也可以试试数组的方式:

// 定义一个结构体保存词和频次
type Word struct {
  text string
  frequency int
}
var words []Word
// 查找某个词,返回索引
func find(word string) int {
} 
// 更新词频
func updateFreq(text string) {
  index := find(text)
  if index >= 0 {
    words[index].frequency++ 
  }
}

数组可以按次序存储统计结果。

5

 

5. 统计与输出

词频统计后,我们按频次排序后输出:

// 按频次对单词排序
sort.Slice(words, func(i, j int) bool {
  return words[i].frequency > words[j].frequency
})
// 按排序后顺序输出结果
for _, w := range words {
  fmt.Println(w.text, w.frequency) 
}

sort.Slice 可以按频次对结果排序。

6

 

6. 主函数逻辑

主函数可以组合上述逻辑完成统计:

func main() {
  text := "hello world hello golang"
  words := tokenize(text)
  // 统计频次 
  for _, w := range words {
    updateFreq(w)
  } 
  // 输出结果
  printResults(words)
}

主函数负责组合调用其他函数完成统计任务。

7

 

7. 程序测试

为了测试程序,可以添加一些测试用例:

func TestWordFrequencies(t *testing.T) {
  text := "hello world hello golang"
  freqs := getFrequencies(text)
  if freqs["hello"] != 2 {
    t.Errorf("hello freq expected 2")
  }
  if freqs["golang"] != 1 {
    t.Errorf("golang freq expected 1")
  } 
}

添加一些简单校验可以测试统计结果。

8

 

8. 优化思考

我们可以考虑以下几点来提升程序:

  • 使用 goroutine 并发分词
func tokenizeConcurrent(text string) []string {
  words := []string{}
  chunks := splitTextIntoChunks(text)
  var wg sync.WaitGroup
  wg.Add(len(chunks))
  for _, chunk := range chunks {
    go func(chunk string) {
      words = append(words, tokenize(chunk)) 
      wg.Done()
    }(chunk)
  }
  wg.Wait()
  return words
}

测试更多边界用例

func TestWordFrequencies(t *testing.T) {
  // 边界 testcase
  testEmpty() 
  testNonAlpha()
  testLongText()
  // 正常 testcase
  testGeneralCase() 
}

数据存储可以考虑 Trie 树等结构

type Node struct {
  children map[rune]*Node
  isWord bool 
}
func buildTrie(words []string) *Node {
  // ...
}
func findWord(root *Node, word string) bool {
  // ...
}

使用 channel 通信

func tokenize(text string, c chan []string) {
  words := // 分词 
  c <- words
}
c := make(chan []string)
go tokenize(text, c)
words := <- c
  • 词频保存到数据库

9

 

9. 扩展练习

一些扩展练习可以考虑:

  • 支持统计中文文本词频
  • 基于词频给文本打标签
  • 生成词云图
  • 支持统计文件词频
  • 增加停用词过滤
  • 构建 inverted index

10

 

总结

到此我们使用 Go 语言实现了一个简单的词频统计程序,并给出了一些改进思路。充分理解各部分功能,对 Go 语言编程理解非常有帮助。可以继续优化代码,实现更多扩展功能。


目录
相关文章
|
8月前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
400 2
|
10月前
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
617 1
|
10月前
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
624 0
|
10月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
444 0
|
10月前
|
Cloud Native Java 中间件
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
488 0
|
10月前
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
594 0
|
10月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
10月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
11月前
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。
|
11月前
|
Go
如何在Go语言的HTTP请求中设置使用代理服务器
当使用特定的代理时,在某些情况下可能需要认证信息,认证信息可以在代理URL中提供,格式通常是:
712 0

热门文章

最新文章