玩出新花样,给你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 语言编程理解非常有帮助。可以继续优化代码,实现更多扩展功能。


目录
相关文章
|
2天前
|
JavaScript Java Go
探索Go语言在微服务架构中的优势
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出。本文将深入探讨Go语言在构建微服务时的性能优势,包括其在内存管理、网络编程、并发模型以及工具链支持方面的特点。通过对比其他流行语言,我们将揭示Go语言如何成为微服务架构中的一股清流。
|
1天前
|
Ubuntu 编译器 Linux
go语言中SQLite3驱动安装
【11月更文挑战第2天】
16 7
|
1天前
|
关系型数据库 Go 网络安全
go语言中PostgreSQL驱动安装
【11月更文挑战第2天】
15 5
|
1天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
13 4
|
2天前
|
SQL 关系型数据库 MySQL
go语言中安装数据库驱动
【11月更文挑战第1天】
16 5
|
1天前
|
存储 设计模式 安全
Go语言中的并发编程:从入门到精通###
本文深入探讨了Go语言中并发编程的核心概念与实践技巧,旨在帮助读者从理论到实战全面掌握Go的并发机制。不同于传统的技术文章摘要,本部分将通过一系列生动的案例和代码示例,直观展示Go语言如何优雅地处理并发任务,提升程序性能与响应速度。无论你是Go语言初学者还是有一定经验的开发者,都能在本文中找到实用的知识与灵感。 ###
|
2天前
|
编译器 Go 开发者
go语言中导入相关包
【11月更文挑战第1天】
11 3
|
1天前
|
安全 Go
用 Zap 轻松搞定 Go 语言中的结构化日志
在现代应用程序开发中,日志记录至关重要。Go 语言中有许多日志库,而 Zap 因其高性能和灵活性脱颖而出。本文详细介绍如何在 Go 项目中使用 Zap 进行结构化日志记录,并展示如何定制日志输出,满足生产环境需求。通过基础示例、SugaredLogger 的便捷使用以及自定义日志配置,帮助你在实际开发中高效管理日志。
9 1
|
2天前
|
关系型数据库 MySQL 数据库连接
go语言中打开数据库连接
【11月更文挑战第1天】
13 2
|
3天前
|
安全 测试技术 Go
Go语言中的并发编程模型解析####
在当今的软件开发领域,高效的并发处理能力是提升系统性能的关键。本文深入探讨了Go语言独特的并发编程模型——goroutines和channels,通过实例解析其工作原理、优势及最佳实践,旨在为开发者提供实用的Go语言并发编程指南。 ####