本文将带您了解关于如何按顺序遍历Golang中的地图?的新内容,同时我们还将为您解释golang遍历map的相关知识,另外,我们还将为您提供关于c–如果给定顺序和后序遍历,如何输出树的前序遍历?、go
本文将带您了解关于如何按顺序遍历Golang中的地图?的新内容,同时我们还将为您解释golang遍历map的相关知识,另外,我们还将为您提供关于c – 如果给定顺序和后序遍历,如何输出树的前序遍历?、golang中range在slice和map遍历中的注意事项、golang中如何遍历可变参数?、Golang中的地图集的实用信息。
本文目录一览:- 如何按顺序遍历Golang中的地图?(golang遍历map)
- c – 如果给定顺序和后序遍历,如何输出树的前序遍历?
- golang中range在slice和map遍历中的注意事项
- golang中如何遍历可变参数?
- Golang中的地图集
如何按顺序遍历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 – 如果给定顺序和后序遍历,如何输出树的前序遍历?
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遍历中的注意事项
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中如何遍历可变参数?
go 中遍历可变参数可以通过 range 关键字,它使用 for-range 循环遍历可变参数的每个值。此外,也可以使用其他方法,如 len() 和 index() 函数、拆包可变参数或使用内置的 reflect 包。
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中的地图集
type Foo struct { title string Tags map[string]string }
如何保持一套独特的结构?根据我的理解,虽然结构相等是一件事 – 地图平等不是.这意味着我无法比较我的上述结构.因此,我不能只实施map as set pattern.
我能想到的两个可能有用的选项是:将标签转换为排序的[] []字符串或use reflect.Deepequal.任何人都有更好的主意?
我解决这个问题的方法就是保留一个结构数组,然后在插入它们时删除任何重复项.
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中的地图集的相关知识,请在本站寻找。
本文标签: