Go 处理整数列表以及查找、添加和删除的最佳方法

Go 处理整数列表以及查找、添加和删除的最佳方法,go,Go,我需要创建一个整数列表,并能够快速添加、删除和查找列表中的项目。虽然我可以创建一个包含它们的字符串和一个处理add/delete/locate的函数,但如果Go能为我处理它,显然更有意义。我看了一下容器/列表,它似乎并不完全合适,但也许我错了 为了快速实现某些功能,我使用了整数数组,但这远远不够理想,我需要找到更好的解决方案。该列表可能最多可容纳1000个值 有人能告诉我在围棋中处理这个问题的“最佳”方法吗?一个例子胜过1000个字。这实际上更像是一个抽象的数据结构问题。答案取决于您的用例。对于

我需要创建一个整数列表,并能够快速添加、删除和查找列表中的项目。虽然我可以创建一个包含它们的字符串和一个处理add/delete/locate的函数,但如果Go能为我处理它,显然更有意义。我看了一下容器/列表,它似乎并不完全合适,但也许我错了

为了快速实现某些功能,我使用了整数数组,但这远远不够理想,我需要找到更好的解决方案。该列表可能最多可容纳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)