解决Golang map range遍历结果不稳定问题
作者:Lucus小秋 发布时间:2024-02-04 06:36:16
标签:Golang,map,range,遍历
闲言少叙,本文主要是想介绍一个Golang开发常见的一个问题。然而,此问题对于初学者来说却经常容易陷入坑中。
问题
我在写一段代码时,使用了Golang的map数据结构,目的是想用map缓存计数结果。简单来说map的键也是整型的,且以递增顺序存储。我的最初想法是,在统计结束后,按照map中存储的键有序输出值。可是,当我运行程序时,结果并不是我想要的,而且有一定概率运行结果不同。
问题代码
func sortByBits(arr []int) []int {
var bitmap = make(map[int][]int, 0)
// map缓存
for i := 0; i < len(arr); i++ {
bits := calBits(arr[i])
if _, ok := bitmap[bits]; !ok {
tmp := make([]int, 0)
tmp = append(tmp, arr[i])
bitmap[bits] = tmp
} else {
bitmap[bits] = append(bitmap[bits], arr[i])
for j := len(bitmap[bits]) - 1;j > 0; j-- {
if bitmap[bits][j] < bitmap[bits][j - 1] {
bitmap[bits][j], bitmap[bits][j - 1] = bitmap[bits][j - 1], bitmap[bits][j]
}
}
}
}
// 输出
var res []int
for _, value := range bitmap {
res = append(res, value...)
}
return res
}
func calBits(n int) int {
sum := 0
for n > 0 {
if n & 1 == 1 {
sum++
}
n = n >> 1
}
return sum
}
当发现这个问题后,我使用二维数组替换map,改造代码如下:
改造代码
func sortByBits(arr []int) []int {
var bitmap = make([][]int, 0, 10000)
// map缓存
for i := 0; i < len(arr); i++ {
bits := calBits(arr[i])
if len(bitmap) <= bits {
length := bits - len(bitmap) + 1
for j := 0; j < length; j++ {
tmp := make([]int, 0)
bitmap = append(bitmap, tmp)
}
}
if len(bitmap[bits]) == 0 {
bitmap[bits] = append(bitmap[bits], arr[i])
} else {
bitmap[bits] = append(bitmap[bits], arr[i])
for j := len(bitmap[bits]) - 1;j > 0; j-- {
if bitmap[bits][j] < bitmap[bits][j - 1] {
bitmap[bits][j], bitmap[bits][j - 1] = bitmap[bits][j - 1], bitmap[bits][j]
}
}
}
}
// 输出
var res []int
for _, value := range bitmap {
res = append(res, value...)
}
return res
}
func calBits(n int) int {
sum := 0
for n > 0 {
if n & 1 == 1 {
sum++
}
n = n >> 1
}
return sum
}
代码很简单,问题也很简单。原理就是Golang的map按键输出结果是随机的,这是语言本身的一个特性,或者说是"坑"。作为开发者,要熟练掌握语言最基本特性,才能开发出最稳健的程序。
补充:golang if _,ok:=range map; ok判断key是否在map中
由于golang没有提供item是否在array当中的判断方法,如果程序里面频繁用到了这种判断,可以将array转化为以array当中的成员为key的map再用上面的方法进行判断,这样会提高判断的效率。
判断方法示例代码
if _, ok := map[key]; ok {
//存在
}
如果每次都for循环,会影响性能!
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。
来源:https://blog.csdn.net/xu070111119/article/details/106539842
0
投稿
猜你喜欢
- 无意间碰到的一个大神整理的Python学习思维导图,感觉对初学者理清学习思路大有裨益,非常感谢他的分享。14 张思维导图基础知识数据类型序列
- 前言故事要从上面这张表情包开始讲起,看到这张表情包之后,我突发奇想,觉得可以将室友上班摸鱼的照片拼接起来,做成表情包叫他起床 激励他学习!!
- random模块用于生成随机数,下面看看模块中一些常用函数的用法:from numpy import randomnumpy.random.
- 研究网页编码很长时间了,因为最近要设计一个友情链接检测的VBS脚本,而与你链接的人的页面很可能是各种编码,以前采取的方法是:如果用GB231
- 本文使用css结合js技术给网页背景background 插入flash播放器播放音乐,想法很大胆,呵呵!刚刚乱试一翻搞出这个,有意思吗?请
- 如果你是一位ASP爱好者,你一定想过ASP的执行效率如何?大家都知道ASP效率和CGI的比,在访问量少的时候,它们是不相上下的,有时可能CG
- 本文效果图:🌻正文注意:我们介绍一下本次开发使用的是uniapp,本次分享内容的搜索框为禁止输入搜索框,点击跳转专属搜索页面。🍉1、查阅官网
- 在安装微软最新数据库SQL Server 2012之前,编者先确定一下安装环境:Windonws 7 SP1,32位操作系统、CPU是2.1
- 这个工具是使用Python开发,可以从下面地址了解详情。官网: https://pypi.org/project/webssh/webssh
- Python 中 list.sort() 是列表中非常常用的排序函数, key 参数可以对单个属性进行排序。但是想要实现类似 sql 中 o
- 本文实例讲述了python通过imaplib模块读取gmail里邮件的方法。分享给大家供大家参考。具体实现方法如下:import imapl
- vue2.0中使用mapState及mapActions的方式 // 使用mapStatecomputed: { &nb
- 在此之前,我写了两篇关于ASP结合XML的贴子,分别介绍了用XML取代数据库和用XML整合数据库这两方面的技术,让数据库在某种情况下不再是我
- 1 捕捉一个异常捕捉一个异常 以用0作为除数会得到ZeroDivisionError异常为例,print(1/0)为例程序的持续执行,不因该
- 使Web系统的开发与维护更加方便,从而有效的节省人力物力,受到了越来越多企业的青眯。 模板引擎是MVC模式建立过程的重要方法,开发者可以设计
- 1.文本string:通用字符串操作re:正则表达式操作difflib:差异计算工具textwrap:文本填充unicodedata:Uni
- 示例代码,用到了函数substr与iconv_substr,mb_substr<html><head><met
- 常用快捷键全部快捷键1、编辑(Editing)2、查找/替换(Search/Replace)3、运行(Running)4、调试(Debugg
- 前言这是一个轮子。大家都知道 Ansible 是功能超级强大的自动化运维工具,十分的高大上。太高大上了以至于在低端运维有点水土不服,在于三点
- 这篇文章介绍如何利用Selenium的方法进行截图,在测试过程中,是有必要截图,特别是遇到错误的时候进行截图。在selenium for P