猿问

在 GO lang 中删除和添加元素到数组

我有 2 个数组声明为 : var input []string和var output []string。


输入数组最初填充了一些 ID。输出数组为 NULL。


每次迭代后,我想从输入数组中删除一个随机元素并将其添加到输出数组中。


最后,输出数组中的所有元素将与输入数组相同(但排序(索引)不同)。


for index := 0; index < len(input); index++ {

    if !visited[index] {

        //do something

    }

}

output[#iteration index] = input[current index]

当我尝试这样做时,我得到array out of bounds error.


隔江千里
浏览 167回答 2
2回答

蝴蝶刀刀

对于output数组,您需要使用append或为其分配初始容量以匹配input.//&nbsp;before&nbsp;the&nbsp;loop output&nbsp;:=&nbsp;make([]string,&nbsp;len(input))将是我的建议,因为append会导致一堆不必要的重新分配,并且您已经知道您需要什么容量,因为它基于input.另一件事是:output&nbsp;=&nbsp;append(output,&nbsp;input[index])但就像我说的,从我观察到的 append 初始容量呈指数增长。如果您没有指定任何内容,这将是基数 2,这意味着您将在达到所需容量之前进行几次不需要的重新分配。

明月笑刀无情

你可以在golang/SliceTricks找到一些有用的技巧。自从引入append内置函数以来container/vector,在 Go 1 中删除的包的大部分功能都可以使用append和复制copy。以下是向量方法及其切片操作类似物:追加向量a = append(a, b...)复制b = make([]T, len(a))copy(b, a)// orb = append([]T(nil), a...)切a = append(a[:i], a[j:]...)删除a = append(a[:i], a[i+1:]...)// ora = a[:i+copy(a[i:], a[i+1:])]删除而不保留顺序a[i] = a[len(a)-1]&nbsp;a = a[:len(a)-1]注意如果元素的类型是一个指针或指针字段,其需要被垃圾收集一个结构,上述实施方式Cut和Delete有潜在的存储器泄露的问题:其值的一些元素仍然由切片引用a并因此不能集。下面的代码可以解决这个问题:切copy(a[i:], a[j:])for k, n := len(a)-j+i, len(a); k < n; k++ {&nbsp; &nbsp; a[k] = nil // or the zero value of T}a = a[:len(a)-j+i]删除copy(a[i:], a[i+1:])a[len(a)-1] = nil // or the zero value of Ta = a[:len(a)-1]删除而不保留顺序a[i] = a[len(a)-1]a[len(a)-1] = nila = a[:len(a)-1]扩张a = append(a[:i], append(make([]T, j), a[i:]...)...)延长a = append(a, make([]T, j)...)插入a = append(a[:i], append([]T{x}, a[i:]...)...)注意第二个append创建一个具有自己底层存储的新切片a[i:],并将元素复制到该切片中,然后将这些元素复制回切片a(由第一个append)。可以使用替代方法避免创建新切片(以及内存垃圾)和第二个副本:插入s = append(s, 0)copy(s[i+1:], s[i:])s[i] = x插入向量a = append(a[:i], append(b, a[i:]...)...)流行音乐x, a = a[0], a[1:]弹回x, a = a[len(a)-1], a[:len(a)-1]推a = append(a, x)推前a = append([]T{ x }, a...)转移x, a := a[0], a[1:]取消移位a = append([]T{x}, a...)额外的技巧过滤而不分配这个技巧利用了一个事实,即切片与原始切片共享相同的后备数组和容量,因此存储被重新用于过滤切片。当然,对原始内容进行了修改。b := a[:0]for _, x := range a {&nbsp; &nbsp; if f(x) {&nbsp; &nbsp; &nbsp; &nbsp; b = append(b, x)&nbsp; &nbsp; }}倒车用相同的元素但以相反的顺序替换切片的内容:for i := len(a)/2-1; i >= 0; i-- {&nbsp; &nbsp; opp := len(a)-1-i&nbsp; &nbsp; a[i], a[opp] = a[opp], a[i]}同样的事情,除了两个索引:for left, right := 0, len(a)-1; left < right; left, right = left+1, right-1 {&nbsp; &nbsp; a[left], a[right] = a[right], a[left]}洗牌费雪-耶茨算法:for i := len(a) - 1; i > 0; i-- {&nbsp; &nbsp; j := rand.Intn(i + 1)&nbsp; &nbsp; a[i], a[j] = a[j], a[i]}
随时随地看视频慕课网APP

相关分类

Go
我要回答