栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

映射订单范围循环

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

映射订单范围循环

如果您需要

map
依次按和键,那么这是2种不同的东西,则需要2种不同的(数据)类型来提供该功能。

带钥匙片

实现此目的的最简单方法是在不同片中维护键顺序。每当您在地图中放入新的货币对时,请先检查密钥是否已在其中。如果不是,则将新密钥添加到单独的片中。当您需要按顺序排列元素时,可以使用按键片。当然,当您移除一对时,您也必须将其从切片中移除。

键片仅包含键(而不包含值),因此开销很小。

将此新功能(map + keys slice)包装为新类型,并为其提供方法,然后隐藏地图和slice。这样就不会发生数据未对齐的情况。

示例实现:

type Key int   // Key typetype Value int // Value typetype Map struct {    m    map[Key]Value    keys []Key}func New() *Map {    return &Map{m: make(map[Key]Value)}}func (m *Map) Set(k Key, v Value) {    if _, ok := m.m[k]; !ok {        m.keys = append(m.keys, k)    }    m.m[k] = v}func (m *Map) Range() {    for _, k := range m.keys {        fmt.Println(m.m[k])    }}

使用它:

m := New()m.Set(1, 11)m.Set(2, 22)m.Range()

在Go Playground上尝试一下。

使用价值包装器实现链接列表

另一种方法是包装值,并且-与实际值一起-还存储下一个/上一个键。

例如,假设您想要类似的地图

map[Key]Value

type valueWrapper struct {    value Value    next  *Key // Next key}

每当将一对添加到地图时,都将设置

valueWrapper
为值,并且必须将其 链接 到上一个(最后一个)对。要 链接
,您必须
next
将最后一个包装器的字段设置为指向此新密钥。为了轻松实现此功能,建议还存储最后一个键(以避免搜索它)。

当您要按插入顺序遍历元素时,您将从第一个开始(必须存储此元素),并且其相关联的内容

valueWrapper
将告诉您下一个键(按插入顺序)。

示例实现:

type Key int   // Key typetype Value int // Value typetype valueWrapper struct {    v    Value    next *Key}type Map struct {    mmap[Key]valueWrapper    first, last *Key}func New() *Map {    return &Map{m: make(map[Key]valueWrapper)}}func (m *Map) Set(k Key, v Value) {    if _, ok := m.m[k]; !ok && m.last != nil {        w2 := m.m[*m.last]        m.m[*m.last] = valueWrapper{w2.v, &k}    }    w := valueWrapper{v: v}    m.m[k] = w    if m.first == nil {        m.first = &k    }    m.last = &k}func (m *Map) Range() {    for k := m.first; k != nil; {        w := m.m[*k]        fmt.Println(w.v)        k = w.next    }}

使用它是相同的。在Go Playground上尝试一下。

注意: 您可能会根据自己的喜好改变一些事情:

  • 您可以将内部地图声明为

    m map[Key]*valueWrapper
    ,这样
    Set()
    就可以更改
    next
    字段而不必分配新的
    valueWrapper

  • 您可以选择

    first
    last
    字段为类型
    *valueWrapper

  • 您可以选择

    next
    类型
    *valueWrapper

比较方式

带有额外切片的方法更容易,更清洁。但是,如果地图变大,则从元素中删除元素可能会变得很慢,因为我们还必须在切片中找到“未排序”的键,因此它很

O(n)
复杂。

即使您将映射添加

prev
valueWrapper
结构中,即使映射很大,也可以轻松扩展value-wrapper中具有link-
list的方法以支持快速元素删除。因此,如果您需要删除一个元素,则可以超快速找到wrapper(
O(1)
),更新prev和next包装器(指向彼此),并执行一个简单的
delete()
操作,即
O(1)

请注意,第一个解决方案(带有分片)中的删除仍然可以通过使用一个额外的映射来加快,该映射将在分片(

map[Key]int
)中从键到键的索引进行映射,因此仍然可以在
O(1)
中实现删除操作,以换取更大的复杂性。加快速度的另一种方法是将映射中的值更改为包装器,该包装器可以保留切片中键的实际值和索引。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/382060.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号