当前位置: 首页 > 面试题库 >

在Go Slice或数组中查找唯一项

阎辰钊
2023-03-14
问题内容

我很新,我现在真的非常困惑。

假设我有一个坐标列表,并且说我在此坐标列表中有一些双打。我一辈子都无法弄清楚如何制作一份独特的清单。通常,在Python中,我可以“欺骗”集合和其他内置函数。在Go中没有那么多。

package main

import (
    "fmt"
    "reflect"
)

type visit struct {
    x, y int
}

func main() {
    var visited []visit
    var unique []visit

    visited = append(visited, visit{1, 100})
    visited = append(visited, visit{2, 2})
    visited = append(visited, visit{1, 100})
    visited = append(visited, visit{1, 1})

    unique = append(unique, visit{1, 1})

    fmt.Println(unique)

    // Go through the visits and find the unique elements
    for _, v := range visited {
        for _, u := range unique {

            fmt.Printf("Here's unique: %v\n", unique)
            fmt.Printf("Comparing %v to %v is %v\n", v, u, reflect.DeepEqual(v, u))

            if reflect.DeepEqual(v, u) {
                fmt.Println("Skip")
            } else {
                unique = append(unique, v)
            }
        }
    }

    fmt.Println(unique)
}

[Run it on Playground](https://play.golang.org/p/7lYjfSaBP0)


问题答案:

您的代码中存在多个错误。最严重的是,由于您要将visited切片的每个特定元素与的 所有
元素进行比较unique,因此如果unique包含至少一个不同的元素,最终将附加它。而且,如果由于unique内部for循环不会“中断”
而有更多不同的元素,您将最终多次追加它。这是不是你想要的,你要追加相等于元素 没有unique

还要注意,struct如果Go中的每个字段都是可比较的,则a
in可比较。由于您的visit结构仅包含2个int字段,因此具有可比性,因此您可以visit简单地将type的值与==运算符进行比较,而不必太丑陋reflect.DeepEqual()。请参见规格:比较运算符:

如果结构的所有字段都是可比较的,则它们的值是可比较的。如果两个结构值对应的非空白字段相等,则它们相等。

这是适用您逻辑的简化正确版本:

visited := []visit{
    visit{1, 100},
    visit{2, 2},
    visit{1, 100},
    visit{1, 1},
}
var unique []visit

for _, v := range visited {
    skip := false
    for _, u := range unique {
        if v == u {
            skip = true
            break
        }
    }
    if !skip {
        unique = append(unique, v)
    }
}

fmt.Println(unique)

输出(在Go Playground上尝试):

[{1 100} {2 2} {1 1}]

另类

确实,Go没有内置的集合类型,但是您可以map[visit]bool轻松地将其用作集合。这样,它变得非常简单!请注意,visit由于它具有可比性,因此可以用作地图中的键(请参见上文)。

visited := []visit{
    visit{1, 100},
    visit{2, 2},
    visit{1, 100},
    visit{1, 1},
}
unique := map[visit]bool{}

for _, v := range visited {
    unique[v] = true
}

fmt.Println(unique)

输出(在Go Playground上尝试):

map[{2 2}:true {1 1}:true {1 100}:true]

唯一的“列表”是地图中键的列表。

如果要将唯一visit值用作切片,请参见以下变体:

var unique []visit
m := map[visit]bool{}

for _, v := range visited {
    if !m[v] {
        m[v] = true
        unique = append(unique, v)
    }
}

fmt.Println(unique)

输出(如预期的那样,在Go Playground上尝试):

[{1 100} {2 2} {1 1}]

请注意,此索引表达式m[v]计算true是否v在地图中(作为键,true是我们存储在地图中的值)。如果v还没有在地图上,m[v]得出这是值类型的零值false的类型bool,正确地告诉该值v还没有在地图上。请参见规格:索引表达式:

对于地图类型 M

…如果地图nil包含或不包含此类条目,a[x]则是的值类型的零值M



 类似资料:
  • 问题内容: 在最近的一次采访中有人问我这个问题。 您将获得一个包含一百万个元素的数组。除了一个元素外,所有元素都是重复的。我的任务是找到独特的元素。 我的做法是要经过在整个数组循环,然后创建一个索引作为数组中和的数组中出现的次数。然后再次遍历我们的地图,并返回值为1的索引。 我说我的方法会花费时间。面试官告诉我要以低于复杂度的方式对其进行优化。我说过,我们不能,因为我们必须遍历具有一百万个元素的整

  • 我试图写一个算法,它需要可变数量的通用数组,存储在中,并收集其中所有唯一的元素(元素只发生一次),并将其存储在一个数组中,称为。例如,数组: 将生成包含内容的数组。 以下是我当前的流程算法: 请注意,是一个数组,它包含

  • 我需要根据下面的2个属性从数组中找到唯一的对象。当“类”和“票价”匹配时,我需要提取唯一的值并在结果数组中获取它们。 来源: 预期结果: 我在SO中查看并能够找到基于一个属性过滤的答案(按属性创建唯一对象数组),但无法找到基于2个属性的答案。

  • 问题内容: 需要在中找到唯一的行。 例如: 我知道我可以创建一个set并在数组上循环,但是我正在寻找一种有效的纯numpy解决方案。我相信有一种方法可以将数据类型设置为,然后我可以使用,但我不知道如何使它工作。 问题答案: 从NumPy 1.13开始,你可以简单地选择轴来选择任何N维数组中的唯一值。要获得唯一的行,可以执行以下操作:

  • 问题内容: 我接受了采访,并且有以下问题: 在不到O(n)的时间内从排序数组中查找唯一数字。 我给出了解决方案,但这是O(n)的。 编辑: 排序后的数组大小约为200亿,唯一数约为1000。 问题答案: 分而治之 : 查看排序序列的第一个和最后一个元素(初始序列为)。 如果两者相等,则序列中的唯一元素是第一个(无论序列有多长)。 如果不同,则划分序列并为每个子序列重复。 一般情况下解决 O(log

  • 我有个算法问题。我试图从一个更大的值集合中找到所有唯一的值子集。 例如,假设我有集。我能用什么算法找到3的这些子集? 子集不应重复,且顺序不重要,因此集{1,2,3}与集{3,2,1}相同。鼓励使用Psudocode(或常规类型)。