当前位置: 首页 > news >正文

50周学习go语言:第五周 复合类型与词频统计

以下是第五周复合类型(数组、切片与映射)的详细学习内容,按照第四周的深度要求设计:


第五周:复合类型与词频统计


一、复合类型详解

1. 数组(Array)
// 声明与初始化
var arr1 [3]int           // 声明:[0 0 0]
arr2 := [3]string{"A", "B", "C"}  // 显式初始化
arr3 := [...]int{1,2,3}   // 编译器推断长度// 特性:
// - 固定长度(长度是类型的一部分)
// - 值传递(赋值/传参产生副本)
// - 内存连续分配// 操作示例:
arr := [5]int{10,20,30,40,50}
fmt.Println(arr[1])       // 20
arr[2] = 35               // 修改元素
fmt.Println(len(arr))     // 5(长度)
fmt.Println(cap(arr))     // 5(容量)
2. 切片(Slice)
// 创建方式
s1 := make([]int, 3, 5)   // 类型,长度,容量
s2 := []float64{1.1, 2.2} // 字面量
s3 := arr[1:3]            // 从数组切割// 特性:
// - 动态大小(自动扩容)
// - 引用类型(底层数组视图)
// - 包含ptr/len/cap三元组// 操作示例:
s := []int{10,20,30}
s = append(s, 40)         // 扩容追加
copy(s[1:], s[2:])        // 删除元素(20)
s = s[:len(s)-1]          // 新长度:[10 30 40]
3. 映射(Map)
// 初始化方式
m1 := make(map[string]int)
m2 := map[string]float64{"pi": 3.1415,"e":  2.7182,
}// 特性:
// - 无序键值对集合
// - 引用类型
// - 线程不安全// 操作示例:
ages := map[string]int{"Alice": 25,"Bob":   30,
}
ages["Charlie"] = 28      // 添加/修改
delete(ages, "Bob")       // 删除
if age, ok := ages["David"]; !ok {fmt.Println("不存在")
}

二、词频统计任务

需求分析
  1. 输入一段英文文本
  2. 输出单词出现频率(不区分大小写)
  3. 过滤标点符号和数字
  4. 支持并发处理(可选优化)
版本1:基础实现
func wordFrequency(text string) map[string]int {// 清理文本cleaner := func(r rune) rune {if unicode.IsLetter(r) {return unicode.ToLower(r)}return ' ' // 非字母转为空格}cleaned := strings.Map(cleaner, text)// 分割单词words := strings.Fields(cleaned)// 统计频率freq := make(map[string]int)for _, word := range words {freq[word]++}return freq
}
版本2:并发优化
func concurrentWordFrequency(text string) map[string]int {// 文本预处理(同上)cleaner := func(r rune) rune {/* 同版本1 */}cleaned := strings.Map(cleaner, text)words := strings.Fields(cleaned)// 并发处理var mu sync.Mutexvar wg sync.WaitGroupfreq := make(map[string]int)chunkSize := 1000for i := 0; i < len(words); i += chunkSize {end := i + chunkSizeif end > len(words) {end = len(words)}chunk := words[i:end]wg.Add(1)go func(words []string) {defer wg.Done()localFreq := make(map[string]int)for _, w := range words {localFreq[w]++}mu.Lock()for k, v := range localFreq {freq[k] += v}mu.Unlock()}(chunk)}wg.Wait()return freq
}

三、测试与性能

1. 表格驱动测试
func TestWordFrequency(t *testing.T) {tests := []struct {input stringwant  map[string]int}{{"Hello hello world",map[string]int{"hello":2, "world":1},},{"Go! 100% Go...",map[string]int{"go":2},},{"A man a plan a canal: Panama",map[string]int{"a":3, "man":1, "plan":1, "canal":1, "panama":1},},}for _, tt := range tests {got := wordFrequency(tt.input)if !reflect.DeepEqual(got, tt.want) {t.Errorf("输入 %q\n期望 %v\n实际 %v", tt.input, tt.want, got)}}
}
2. 性能基准测试
# 运行测试
go test -bench . -benchmem# 预期结果:
BenchmarkWordFrequency-8             5000    324521 ns/op   138920 B/op    502 allocs/op
BenchmarkConcurrent-8                8000    198745 ns/op   189654 B/op   1502 allocs/op

四、进阶技巧

1. 内存优化(预分配)
// 预估容量减少扩容
words := make([]string, 0, len(text)/5)  // 按平均单词长度5预估
freq := make(map[string]int, 1000)       // 预分配哈希表槽位
2. 正则表达式优化
// 使用正则分割更高效
re := regexp.MustCompile(`\W+`)
words := re.Split(strings.ToLower(text), -1)
3. 自定义排序输出
func sortedFrequency(freq map[string]int) []string {type pair struct {word  stringcount int}pairs := make([]pair, 0, len(freq))for k, v := range freq {pairs = append(pairs, pair{k, v})}sort.Slice(pairs, func(i, j int) bool {return pairs[i].count > pairs[j].count})result := make([]string, len(pairs))for i, p := range pairs {result[i] = fmt.Sprintf("%s:%d", p.word, p.count)}return result
}

五、扩展练习

  1. 停用词过滤

    func filterStopWords(freq map[string]int, stopWords map[string]struct{}) {for w := range freq {if _, exists := stopWords[w]; exists {delete(freq, w)}}
    }
    
  2. 词云生成器

    func generateWordCloud(freq map[string]int, size int) []string {// 根据频率生成不同字号标记// 示例:["GO(12)", "语言(8)", "并发(20)"]
    }
    

六、学习检查清单

  • 能正确定义数组、切片和映射
  • 理解切片扩容机制(容量翻倍策略)
  • 会使用sync.Mutex处理并发map访问
  • 能解释数组与切片的底层关系
  • 理解map的哈希表实现原理
  • 会进行切片的内存预分配优化
  • 能处理Unicode字符的文本清洗
  • 会编写并发安全的统计程序

通过本学习内容,您将掌握Go语言核心复合类型的特性和高效使用方法,并能够根据实际场景选择最佳数据结构。建议:

  1. 尝试处理1GB以上的大文本文件
  2. 比较不同分块策略对并发版本的影响
  3. 使用pprof分析内存分配热点
  4. 实现扩展练习中的词云可视化功能

相关文章:

50周学习go语言:第五周 复合类型与词频统计

以下是第五周复合类型&#xff08;数组、切片与映射&#xff09;的详细学习内容&#xff0c;按照第四周的深度要求设计&#xff1a; 第五周&#xff1a;复合类型与词频统计 一、复合类型详解 1. 数组&#xff08;Array&#xff09; // 声明与初始化 var arr1 [3]int …...

HTTP非流式请求 vs HTTP流式请求

文章目录 HTTP 非流式请求 vs 流式请求一、核心区别 服务端代码示例&#xff08;Node.js/Express&#xff09;非流式请求处理流式请求处理 客户端请求示例非流式请求&#xff08;浏览器fetch&#xff09;流式请求处理&#xff08;浏览器fetch&#xff09; Python客户端示例&…...

深圳南柯电子|医疗设备EMC测试整改检测:零到一,保障医疗安全

在当今医疗科技飞速发展的时代&#xff0c;医疗设备的电磁兼容性&#xff08;EMC&#xff09;已成为确保其安全、有效运行的关键要素之一。EMC测试整改检测不仅关乎设备的性能稳定性&#xff0c;更是保障患者安全、避免电磁干扰引发医疗事故的重要措施。 一、医疗设备EMC测试整…...

详解:事务注解 @Transactional

创作内容丰富的干货文章很费心力&#xff0c;感谢点过此文章的读者&#xff0c;点一个关注鼓励一下作者&#xff0c;激励他分享更多的精彩好文&#xff0c;谢谢大家&#xff01; Transactional 是 Spring Framework 中常用的注解之一&#xff0c;它可以被用于管理事务。通过使…...

【虚拟仪器技术】labview操作指南和虚拟仪器技术习题答案(一)

今天是2025年2月24日&#xff0c;画的是fate/Grand Order里面的阿尔托莉雅.卡斯特&#xff0c;武内老师的画。 目录 第1章 第2章 第3章 第4章 第5章 关注作者了解更多 我的其他CSDN专栏 毕业设计 求职面试 大学英语 过程控制系统 工程测试技术 虚拟仪器技术 可编程…...

在Linux桌面上创建Idea启动快捷方式

1、在桌面新建idea.desktop vim idea.desktop [Desktop Entry] EncodingUTF-8 NameIntelliJ IDEA CommentIntelliJ IDEA Exec/home/software/idea-2021/bin/idea.sh Icon/home/software/idea-2021/bin/idea.svg Terminalfalse TypeApplication CategoriesApplication;Developm…...

渗透测试(WAF过滤information_schema库的绕过,sqllib-46关,海洋cms9版本的注入)

1.sqlin-lib 46关 打开网站配置文件发现 此网站的对ID进行了排序&#xff0c;我们可以知道&#xff0c;order by接不了union &#xff0c;那我们可以通过测试sort&#xff0c;rond等函数&#xff0c;观察网页的反馈来判断我们的盲注是否正确 我们发现 当参数有sort来排序时&…...

Unity基础——资源导出分享为Unity Package

一.选中要打包的文件夹&#xff0c;右击&#xff0c;点击Exporting package 二.勾选 Include Dependencies&#xff0c;点击Export Include Dependencies&#xff1a;代表是否包含资源依赖的选项 三.选择保存的位置&#xff0c;即可生成Unity package 最终形成文件&#xff1a…...

C语言【指针篇】(三)

C语言【指针篇】&#xff08;三&#xff09; 前言正文1. 数组名的理解2. 使用指针访问数组3. 一维数组传参的本质4. 冒泡排序5. 二级指针6. 指针数组7. 指针数组模拟二维数组 总结 前言 本文主要基于前面对指针的掌握&#xff0c;进一步学习&#xff1a;数组名的理解、使用指针…...

DevSecOps普及:安全与开发运维的深度融合

一、引言 随着软件开发模式的演进&#xff0c;DevOps已成为现代软件工程的主流实践。然而&#xff0c;在传统的DevOps流程中&#xff0c;安全往往被视为开发和运维之外的额外环节&#xff0c;导致安全漏洞在产品交付后才被发现&#xff0c;增加了修复成本和风险。为了解决这一…...

【JAVA-数据结构】Map和Set

上一篇我们聊到了排序相关内容&#xff0c;这一篇我们对Map和Set进行一系列说明&#xff0c;大家自取。 1.搜索树 1.1 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节…...

从 0 到 1,用 Python 构建超实用 Web 实时聊天应用

从 0 到 1&#xff0c;用 Python 构建超实用 Web 实时聊天应用 本文深入剖析如何运用 Python 的 Flask 框架与 SocketIO 扩展&#xff0c;搭建一个功能完备的 Web 实时聊天应用。从环境搭建、前后端代码实现&#xff0c;到最终运行展示&#xff0c;逐步拆解关键步骤&#xff0…...

轻松搭建:使用Anaconda创建虚拟环境并在PyCharm中配置

一、使用Anaconda创建虚拟环境 1. 安装Anaconda 2..conda常用的命令 3. 创建虚拟环境-以搭建MachineVision为例 4. 激活虚拟环境 5. 安装依赖包 二、PyCharm配置环境 在进行Python项目开发时&#xff0c;合理的环境管理是必不可少的&#xff0c;特别是当你在多个项目中…...

【新人系列】Python 入门专栏合集

✍ 个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4dd; 专栏地址&#xff1a;https://blog.csdn.net/newin2020/category_12801353.html &#x1f4e3; 专栏定位&#xff1a;为 0 基础刚入门 Python 的小伙伴提供详细的讲解&#xff0c;也欢迎大佬们…...

linux ununtu安装mysql 怎么在my.cnf文件里临时配置 无密码登录

在 Ubuntu 中&#xff0c;若需通过修改 my.cnf 临时禁用 MySQL 的密码验证&#xff08;例如忘记 root 密码需要重置&#xff09;&#xff0c;可以通过添加 skip-grant-tables 选项实现。以下是具体步骤&#xff1a; 步骤 1&#xff1a;编辑 MySQL 配置文件 1. 打开 MySQL 配置…...

git,bash - 从一个远端git库只下载一个文件的方法

文章目录 git,bash - 从一个远端git库只下载一个文件的方法概述笔记写一个bash脚本来自动下载get_github_raw_file_from_url.shreanme_file.shfind_key_value.sh执行命令 END git,bash - 从一个远端git库只下载一个文件的方法 概述 github上有很多大佬上传了电子书库&#xf…...

python生成的exe文件防止反编译(pyinstaller加密)

python生成的exe文件可以轻松的被破解&#xff0c;为了防止反编译&#xff0c;知乎友友们给出了很多不同的见解&#xff0c;其中主流的回答是pyinstaller加密和niutka打包python&#xff0c;本篇介绍的方法是第一种&#xff0c;pyinstaller打包的时候进行加密&#xff0c;防破解…...

Android移动应用开发实践-1-下载安装和简单使用Android Studio 3.5.2版本(频频出错)

一、下载安装 1.Android Studio3.5.2下载地址&#xff1a;Android Studio3.5.2下载地址 其他版本下载地址&#xff1a;其他版本下载地址 2.安装教程&#xff08;可以多找几个看看&#xff09; 安装 | 手把手教你Android studio 3.5.2安装&#xff08;安装教程&#xff09;_a…...

Android Audio实战——音频相关基础概念(附)

Android Audio 开发其实就是媒体源数字化的过程,通过将声波波形信号通过 ADC 转换成计算机支持的二进制的过程叫做音频采样 (Audio Sampling)。采样 (Sampling) 的核心是把连续的模拟信号转换成离散的数字信号。 一、声音的属性 1、响度 (Loudness) 响度是指人类可以感知到的…...

5分钟使用Docker部署Paint Board快速打造专属在线画板应用

文章目录 前言1.关于Paint Board2.本地部署paint-board3.使用Paint Board4.cpolar内网穿透工具安装5.创建远程连接公网地址6.固定Paint Board公网地址 &#x1f4a1; 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...

aardio 自动识别验证码输入

技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”&#xff0c;于是尝试整合图像识别与网页自动化技术&#xff0c;完成了这套模拟登录流程。核心思路是&#xff1a;截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...