Go 处理整数列表以及查找、添加和删除的最佳方法
我需要创建一个整数列表,并能够快速添加、删除和查找列表中的项目。虽然我可以创建一个包含它们的字符串和一个处理add/delete/locate的函数,但如果Go能为我处理它,显然更有意义。我看了一下容器/列表,它似乎并不完全合适,但也许我错了 为了快速实现某些功能,我使用了整数数组,但这远远不够理想,我需要找到更好的解决方案。该列表可能最多可容纳1000个值Go 处理整数列表以及查找、添加和删除的最佳方法,go,Go,我需要创建一个整数列表,并能够快速添加、删除和查找列表中的项目。虽然我可以创建一个包含它们的字符串和一个处理add/delete/locate的函数,但如果Go能为我处理它,显然更有意义。我看了一下容器/列表,它似乎并不完全合适,但也许我错了 为了快速实现某些功能,我使用了整数数组,但这远远不够理想,我需要找到更好的解决方案。该列表可能最多可容纳1000个值 有人能告诉我在围棋中处理这个问题的“最佳”方法吗?一个例子胜过1000个字。这实际上更像是一个抽象的数据结构问题。答案取决于您的用例。对于
有人能告诉我在围棋中处理这个问题的“最佳”方法吗?一个例子胜过1000个字。这实际上更像是一个抽象的数据结构问题。答案取决于您的用例。对于一般情况(查看
append
等),一个int片段就可以了,但是如果您想找到比O(n)更好的项,那么您就需要对它们进行排序,并且插入到排序的int[]
中的最坏情况是O(n)iirc
所以问题是你想优化、索引、添加、删除还是搜索哪个?为了保持简单,我会使用。地图是非常快速、高效和内置的 () 产生 Found 2 Didn't Find 8 Contents 3 Contents 1 发现2 没有找到8个 内容3 内容1
此解决方案的唯一缺点可能是整数没有按任何特定顺序保存,这可能对您的应用程序很重要,也可能不重要。没有“最佳”方式来回答您的问题,因为您没有说明您想做什么或做什么 这种表现对你很重要。数据结构的问题是,每个结构 根据具体情况,性能会更好或更差。通常我会说一个整数切片 对于1000个条目,它的性能相当好,使用起来也不难。也是解决方案 proposed很吸引人,因为它为您的值提供了
O(1)
lookup time(平均!),而不是
O(n)
(未排序)或O(log n)
(排序)数组中的搜索时间
Go提供了一些操作来实现您建议的[]int
存储:
- 获取:
x[i]
- 插入:
或x[i]=j
或使用排序插入x=append(x,j)
- 删除:
x=append(x[:i],x[i+1:]…)
- 搜索:如果使用排序插入,则可以使用,否则需要循环并线性搜索
[]int
使用O(logn)
搜索时间和O(n)
插入时间。检索、删除和设置
当然,索引是O(1)
type Ints[]int
//插入v以便对整数进行排序
func(整数*整数)追加(v整数){
i:=sort.SearchInts(*ints,v)
*ints=append((*ints)[:i],append([]int{v},(*ints)[i:])
}
//按索引删除
func(整数*整数)删除(整数){
*ints=append((*ints)[:i],(*ints)[i+1:]…)
}
func(int)搜索(v int)(int,bool){
i:=sort.SearchInts(ints,v)
返回i,i
正如您在示例中所看到的,Append
搜索插入新值的位置,具体取决于
在大小上,按升序对切片内容进行有效排序。这使它成为可能
通过sort.SearchInts
使用二进制搜索,将搜索时间从O(n)
缩短到O(log n)
。
因此,在插入时进行排序的成本也随之增加,而这又是通过搜索一个插槽来完成的,而
最坏情况下的成本
O(logn)
。因此,插入也是O(logn)
。实际上不需要使用bool作为值<代码>结构{}(一个空结构)就可以了。我已经更改了我的代码以使用所描述的映射。关于map解决方案,我有一些不喜欢的地方,但它们不是什么大问题。@Brian哦,如果使用内置类型map
,您确实需要一个值,并且没有好的替代方法bool
是传统的使用方法,因此您可以使用if xs[2]
测试是否存在,这是一种方便<代码>布尔值s至少很小@使用struct{}
的nemo将起作用,但我认为它并不能确定它是否真的节省了您的空间。@NickCraig-Wood是的,它节省了您的内存。看见如果你为它创建一个类型,它并不难看,例如,type empty struct{}
@nemo是的,最新go的内存使用率是正确的,而内存减少了32%。谢谢大家的回答。我认为搜索/删除都很重要,因为它们都是相关的。秩序不重要。序列是将整数值添加到“列表”,做一些工作,然后删除它。在其他位置(延迟),检查值是否存在,如果存在,请执行某些操作并将其删除。@BrianOh您确定无法使用通道实现您的过程吗?听起来很像消费者/制作人…@nemo。我不认为频道是解决方案(我可能错了)。Go程序是一个http服务器,为各种客户机提供服务。整数的“列表”包含每个特定客户端的唯一增量id。数据库的更新随时可能中止,这由一个传递唯一id的“延迟”回滚函数调用来处理。如果更新完成OK(提交),它将从“列表”中删除int id。因此,当调用Rollback函数时,如果惟一id不在列表中,它将简单地返回。否则,它将执行回滚并从列表中删除唯一的id。@BrianOh如果您使用整数列表明确地告诉延迟函数数据库更新正常,这可能有点过分。您可以将数据库响应存储在延迟的闭包中。看,尼莫。谢谢,这看起来是个不错的解决方案
Found 2
Didn't Find 8
Contents 3
Contents 1
type Ints []int
// Insert v so that ints is sorted
func (ints *Ints) Append(v int) {
i := sort.SearchInts(*ints, v)
*ints = append((*ints)[:i], append([]int{v}, (*ints)[i:]...)...)
}
// Delete by index
func (ints *Ints) Delete(i int) {
*ints = append((*ints)[:i], (*ints)[i+1:]...)
}
func (ints Ints) Search(v int) (int, bool) {
i := sort.SearchInts(ints, v)
return i, i < len(ints) && ints[i] == v
}
data := make(Ints, 0, 1000)
data.Append(100)
index,ok := data.Search(10)