GVKun编程网logo

如何按顺序遍历Golang中的地图?(golang遍历map)

14

本文将带您了解关于如何按顺序遍历Golang中的地图?的新内容,同时我们还将为您解释golang遍历map的相关知识,另外,我们还将为您提供关于c–如果给定顺序和后序遍历,如何输出树的前序遍历?、go

本文将带您了解关于如何按顺序遍历Golang中的地图?的新内容,同时我们还将为您解释golang遍历map的相关知识,另外,我们还将为您提供关于c – 如果给定顺序和后序遍历,如何输出树的前序遍历?、golang中range在slice和map遍历中的注意事项、golang中如何遍历可变参数?、Golang中的地图集的实用信息。

本文目录一览:

如何按顺序遍历Golang中的地图?(golang遍历map)

如何按顺序遍历Golang中的地图?(golang遍历map)

请看下面我的地图

var romanNumeralDict map[int]string = map[int]string{  1000: "M",  900 : "CM",  500 : "D",  400 : "CD",  100 : "C",  90  : "XC",  50  : "L",  40  : "XL",  10  : "X",  9   : "IX",  5   : "V",  4   : "IV",  1   : "I",}

我正在按钥匙的大小顺序遍历此地图

  for k, v := range romanNumeralDict {    fmt.Println("k:", k, "v:", v)  }

但是,这打印出来

k: 1000 v: Mk: 40 v: XLk: 5 v: Vk: 4 v: IVk: 900 v: CMk: 500 v: Dk: 400 v: CDk: 100 v: Ck: 90 v: XCk: 50 v: Lk: 10 v: Xk: 9 v: IXk: 1 v: I

有没有一种方法可以按键的大小顺序打印出来,所以,我想像这样遍历这张地图

k:1K:4K:5K:9k:10

等等…

非常感谢您的帮助!

答案1

小编典典

收集所有键,对它们进行排序,然后按键迭代地图,如下所示:

keys := make([]int, 0)for k, _ := range romanNumeralDict {    keys = append(keys, k)}sort.Ints(keys)for _, k := range keys {    fmt.Println(k, romanNumeralDict[k])}

c – 如果给定顺序和后序遍历,如何输出树的前序遍历?

c – 如果给定顺序和后序遍历,如何输出树的前序遍历?

给出了在我有预订顺序和整数数组中的inorder遍历时输出树的后序遍历的代码.我如何同样获得带有inorder和postorder数组的预订顺序?

void postorder( int preorder[],int prestart,int inorder[],int inostart,int length)
{ 
  if(length==0) return; //terminating condition
  int i;
  for(i=inostart; i<inostart+length; i++)
    if(preorder[prestart]==inorder[i])//break when found root in inorder array
      break;
  postorder(preorder,prestart+1,inorder,inostart,i-inostart);
  postorder(preorder,prestart+i-inostart+1,i+1,length-i+inostart-1);
  cout<<preorder[prestart]<<" ";
}

这是preorder()的原型

void preorder(int inorderorder [],int postorder [],int poststart,int length)

使用postorder()就可以了

int preorder[6]={6,4,1,5,8,9};
int inorder[6]={1,6,9};
postorder( preorder,6);

out put将是

1 5 4 9 8 6

下面是print_preorder()的错误代码,仍然无法在下面工作

void print_preorder( int inorder[],int postorder[],int length)
    {
      if(length==0) return; //terminating condition
      int i;
      for(i=inostart; i<inostart+length; i++)
        if(postorder[poststart+length-1]==inorder[i])
          break; 
      cout<<postorder[poststart+length-1]<<" ";
      print_preorder(inorder,postorder,poststart,i-inostart);
      print_preorder(inorder,inostart+i-poststart+1,length-i+inostart-1);
    }

解决方法

这里有一些提示:

>后序子阵列中的最后一个元素是您的新预订根.
> inorder数组可以在新预订根的任一侧拆分为两个.
>您可以在这两个inorder子数组上以递归方式调用print_preorder函数.
>调用print_preorder函数时,inorder和postorder数组的大小相同.
>你有一个越界数组访问:postorder [poststart length]超过了数组的结尾.要获得最后一个元素,您需要postorder [poststart length-1]
>您的第一个递归print_preorder函数选择了错误的长度.请记住,length是子数组的长度,但inostart是inorder数组中的绝对位置.您的函数可能会以负长度调用.
>你的第二个递归函数对于转换边界和长度来说相当遥远.它可能有助于在纸上绘制并跟踪您的算法.

绘制树可能有所帮助:

6
   /   \
  4     8
 / \     \
1   5     9

然后写出三个遍历:

// index:         0 1 2 3 4 5
int postorder[6]={1,9,6};
int inorder[6]=  {1,9};
int preorder[6]= {6,9};

现在,放下电脑,拿出笔和电脑.纸和思考问题:)

想象一下这个调用堆栈(新的根目录打印在左侧):

6 print_preorder(len=6,in=[1 4 5 6 8 9],post=[1 5 4 9 8 6])
4 |-> print_preorder(len=3,in=[1 4 5],post=[1 5 4])
1 |   |-> print_preorder(len=1,in=[1],post=[1])
  |   |   |-> print_preorder(len=0,in=[],post=[])
  |   |   |-> print_preorder(len=0,post=[])
5 |   |-> print_preorder(len=1,in=[5],post=[5])
  |       |-> print_preorder(len=0,post=[])
  |       |-> print_preorder(len=0,post=[])
8 |-> print_preorder(len=2,in=[8 9],post=[9 8])
      |-> print_preorder(len=0,post=[])
9     |-> print_preorder(len=1,in=[9],post=[9])
          |-> print_preorder(len=0,post=[])
          |-> print_preorder(len=0,post=[])

祝好运 :)

golang中range在slice和map遍历中的注意事项

golang中range在slice和map遍历中的注意事项

golang中range在slice和map遍历中的注意事项

package main
import (
 "fmt"
)
func main() {
 slice := []int{0, 1, 2, 3}
 myMap := make(map[int]*int)
 for _,v :=range slice{
 if v==1 {
  v=100
 }
 }
 for k,v :=range slice{
 fmt.Println("k:",k,"v:",v)
 }
}

预想的结果应该是:

k: 0 v: 0
k: 1 v: 100
k: 2 v: 2
k: 3 v: 3

坑,但是实际上

k: 0 v: 0
k: 1 v: 1
k: 2 v: 2
k: 3 v: 3

slice的值并没有改变,出现上述问题的原因是因为for range遍历的内容是对原内容的一个拷贝,所以不能用来修改原切片中内容。

使用 k根据索引直接修改值。

for k,v :=range slice{
 if v==1 {
  slice[k]=100
 }
 }

另外一个

 package main
  import (
   "fmt"
  )
  func main() {
   s :=[]int{1,2,3,4}
   m :=make(map[int]*int)
   for k,v:=range s{
   m[k]=&v
   }
   for key, value := range m {
   fmt.Printf("map[%v]=%v\n", key, *value)
   }
   fmt.Println(m)
  }

预期打印的值应该为:

map[0]=1
map[1]=2
map[2]=3
map[3]=4

实际结果:

map[2]=4
map[3]=4
map[0]=4
map[1]=4

从上面结果我们可以猜想到,range指向的都是同一个指针。通过Println我们可以验证下我们的猜想

map[1:0xc00008a000 2:0xc00008a000 3:0xc00008a000 0:0xc00008a000],我们可以看到我们的猜想是正确的

其实还是因为for range创建的是每个元素的拷贝,而不是直接返回每个元素的引用,如果使用该值变量的地址作为指向每个元素的指针,就会导致错误,在迭代时,返回的变量是一个迭代过程中根据切片依次赋值的新变量,所以值的地址总是相同的,导致结果不如预期。

声明一个中间变量,保存value,并且复制给map即可

package main
import (
 "fmt"
)
func main() {
 s :=[]int{1,2,3,4}
 m :=make(map[int]*int)
 for k,v:=range s{
 n:=v
 m[k]= &n
 }
 for key, value := range m {
 fmt.Printf("map[%v]=%v\n", key, *value)
 }
 fmt.Println(m)
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接

您可能感兴趣的文章:
  • golang中for range的取地址操作陷阱介绍
  • 解决Golang map range遍历结果不稳定问题
  • 关于Golang中range指针数据的坑详解
  • Golang range slice 与range array 之间的区别

golang中如何遍历可变参数?

golang中如何遍历可变参数?

go 中遍历可变参数可以通过 range 关键字,它使用 for-range 循环遍历可变参数的每个值。此外,也可以使用其他方法,如 len() 和 index() 函数、拆包可变参数或使用内置的 reflect 包。

golang中如何遍历可变参数?

Go 中如何遍历可变参数

在 Go 语言中,可变参数使用 ... 语法表示,它允许您向函数传递任意数量的参数。遍历可变参数的方法如下:

使用 range 关键字

立即学习“go语言免费学习笔记(深入)”;

func printValues(values ...int) {
    for _, value := range values {
        fmt.Println(value)
    }
}
登录后复制

实战案例

假设我们有一个函数,它接收一个可变数量的整数并返回它们的总和。我们可以通过遍历可变参数并使用 + 运算符来编写此函数。

func sumValues(values ...int) int {
    var sum int
    for _, value := range values {
        sum += value
    }
    return sum
}

func main() {
    result := sumValues(1, 2, 3, 4, 5)
    fmt.Println("结果:", result)
}
登录后复制

输出:

结果: 15
登录后复制

其他方法

除了 range 关键字之外,还可以使用其他方法来遍历可变参数:

  • 使用 len() 和 index() 函数: len() 函数返回可变参数的长度,而 index() 函数返回指定索引处的参数。
  • 拆包可变参数: 可将可变参数拆包到一个切片中,然后遍历切片。
  • 使用内置的 reflect 包: reflect 包提供了 ValueOf() 和 Len() 函数,可用于获取可变参数的类型和长度。

以上就是golang中如何遍历可变参数?的详细内容,更多请关注php中文网其它相关文章!

Golang中的地图集

Golang中的地图集

如果我有一个像这样的结构:
type Foo struct {
  title string
  Tags map[string]string
}

如何保持一套独特的结构?根据我的理解,虽然结构相等是一件事 – 地图平等不是.这意味着我无法比较我的上述结构.因此,我不能只实施map as set pattern.

我能想到的两个可能有用的选项是:将标签转换为排序的[] []字符串或use reflect.Deepequal.任何人都有更好的主意?

有几种方法可以实现这一点. James Henstridge实际上有一个好主意,我试图实现它.如果没有我自己的哈希算法,它首先使用map就表现得非常糟糕.

我解决这个问题的方法就是保留一个结构数组,然后在插入它们时删除任何重复项.

package structset

type Foo struct {
  title string
  Tags  map[string]string
}

func (f Foo) Equals(f2 Foo) bool {
  if f.title != f2.title {
    return false
  }

  if len(f.Tags) != len(f2.Tags) {
    return false
  }

  for k,v := range f.Tags {
    if w,ok := f2.Tags[k]; !ok || v != w {
      return false
    }
  }

  return true
}

type FooSet []Foo

func (this FooSet) Add(value Foo) {
  if !this.Contains(value) {
    this = append(this,value)
  }
}

func (this FooSet) Length() int {
  return len(this)
}

func (this FooSet) Contains(f Foo) bool {
  for _,v := range this {
    if v.Equals(f) {
      return true
    }
  }
  return false
}

func NewSet() FooSet {
  return FooSet(make([]Foo,100))
}

我在i7-3770K Windows机器上对此进行了基准测试,得到了:

BenchmarkSmallSetWithFewCollisions         50000             46615 ns/op
BenchmarkSmallSetWithMoreCollisions        50000             46575 ns/op
BenchmarkSmallSetWithManyCollisions        50000             46605 ns/op
BenchmarkMediumSetWithFewCollisions         1000           2335296 ns/op
BenchmarkMediumSetWithMoreCollisions        1000           2352298 ns/op
BenchmarkMediumSetWithManyCollisions        1000           2336796 ns/op
BenchmarkLargeSetWithFewCollisions            50          46805944 ns/op
BenchmarkLargeSetWithMoreCollisions           50          47376016 ns/op
BenchmarkLargeSetWithManyCollisions           50          46815946 ns/op

要获得非常少的性能,您可以先将所有数据插入到数组中,然后删除所有重复数据.

删除重复代码是:

func (this FooSet) RemoveDuplicates() {
  length := len(this) - 1
  for i := 0; i < length; i++ {
    for j := i + 1; j <= length; j++ {
      if this[i].Equals(this[j]) {
        this[j] = this[length]
        this = this[0:length]
        length--
        j--
      }
    }
  }
}

这方面的基准是:

BenchmarkSmallSetWithFewCollisions         50000             45245 ns/op
BenchmarkSmallSetWithMoreCollisions        50000             45615 ns/op
BenchmarkSmallSetWithManyCollisions        50000             45555 ns/op
BenchmarkMediumSetWithFewCollisions         1000           2294791 ns/op
BenchmarkMediumSetWithMoreCollisions        1000           2309293 ns/op
BenchmarkMediumSetWithManyCollisions        1000           2286290 ns/op
BenchmarkLargeSetWithFewCollisions            50          46235870 ns/op
BenchmarkLargeSetWithMoreCollisions           50          46515906 ns/op
BenchmarkLargeSetWithManyCollisions           50          45865824 ns/op

这是将Foo分配给地图[string] Foo的基准.

BenchmarkSmallSetWithFewCollisions         50000             65718 ns/op
BenchmarkSmallSetWithMoreCollisions        50000             64238 ns/op
BenchmarkSmallSetWithManyCollisions        50000             55016 ns/op
BenchmarkMediumSetWithFewCollisions          500           3429435 ns/op
BenchmarkMediumSetWithMoreCollisions         500           3117395 ns/op
BenchmarkMediumSetWithManyCollisions        1000           2826858 ns/op
BenchmarkLargeSetWithFewCollisions            20          82635495 ns/op
BenchmarkLargeSetWithMoreCollisions           20          85285830 ns/op
BenchmarkLargeSetWithManyCollisions           20          73659350 ns/op

在我看来,即使地图是可以清洗的,它仍然表现不佳.

关于如何按顺序遍历Golang中的地图?golang遍历map的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于c – 如果给定顺序和后序遍历,如何输出树的前序遍历?、golang中range在slice和map遍历中的注意事项、golang中如何遍历可变参数?、Golang中的地图集的相关知识,请在本站寻找。

本文标签: