在golang中使用映射解决问题时,每次运行代码时都会产生不同且错误的输出



我在做去年代码降临节的第07天,并用Python解决了它(像这样(
我正在努力学习围棋,并在围棋中尝试了类似的方法。我将所有关系存储在map中,如下所示:

map[baseColour1:[Colours{subColour1, noOfBags}, Colours{subColour2, noOfBags}...], baseColour2:...

以下是迄今为止的完整代码:

package main
import (
"bufio"
"fmt"
"os"
"regexp"
"strings"
"strconv"
)
// Part 1
// Find relation between all the colours
type Colours struct {
subColour   string
noOfBag     int
}
// To reuse for Part 2
func relationBetweenColours(input [][]string) (relation map[string][]Colours) {
relation = make(map[string][]Colours)
for _, rule := range input {
baseColour := strings.Join(rule[:2], " ")
relation[baseColour] = make([]Colours, 0)
for i := range rule {
match, _ := regexp.MatchString("\d", rule[i])
if match {
subColour := strings.Join(rule[i + 1:i + 3], " ")
noOfBag, _ := strconv.Atoi(rule[i])
relation[baseColour] = append(relation[baseColour], Colours{subColour, noOfBag})
}
}
}
return
}
func checkMembership(input []string, element string) (bool) {
for _, value := range input {
if (value == element) { return true }
}
return false
}
func part1(relation map[string][]Colours) (count int) {
// Strip relation of extra information
relevantRelation := make(map[string][]string)
for baseColour, arrayOfColours := range relation {
relevantRelation[baseColour] = make([]string, 0)
for _, colour := range arrayOfColours {
relevantRelation[baseColour] = append(relevantRelation[baseColour], colour.subColour)
}
}
// Add indirectly related colours
for baseColour, arrayOfColours := range relevantRelation {
for _, colour := range arrayOfColours {
// Get an array of all colours which is not linked to baseColour
for _, subColour := range relevantRelation[colour] {
if !checkMembership(relevantRelation[baseColour], subColour) {
relevantRelation[baseColour] = append(relevantRelation[baseColour], subColour)
}
}
}
}
// Add no. of colours which can eventually contain a "shiny gold" bag
for _, arrayOfColours := range relevantRelation {
if checkMembership(arrayOfColours, "shiny gold") {
count++
}
}
return
}
func main() {
// Read input
file, _ := os.Open("input.txt")
defer file.Close()
scanner := bufio.NewScanner(file)
var input [][]string
for scanner.Scan() {
rule := strings.Split(scanner.Text(), " ")
input = append(input, rule)
}
relation := relationBetweenColours(input)
fmt.Println(part1(relation))
}

当我对问题中给出的小样本输入尝试我的代码时,它产生了正确的结果
然而,在根据给我的全部输入运行它时,它每次都会产生看似不同且错误的结果。输出在10到50之间,每次都会发生变化(对于第1部分的输入,正确答案是213(。

我的问题是:

  1. 这里到底发生了什么,每次都会导致不同的结果
  2. 我能做些什么来克服这个问题并解决这个问题

Golang地图未排序。因此,存储当时值和检索值的方式将影响订单的读取方式。你可以做的一件事是按照你的意愿对映射键进行排序,然后使用它。或者你可以创建一个带有索引/键的切片来映射。这将有你设定的顺序。

func getOrderedKeys(myMap map[string][]Colours) []string {
keys := make([]string, 0)
for k, _ := range collection {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}

现在,每次使用此贴图时,都要获取排序的关键帧,然后使用这些关键帧来获取贴图值。

如果你不想有排序的键,你可以做的其他事情就是创建一个切片,并将其用作排序的键。

func relationBetweenColours(input [][]string) (relation map[string][]Colours, keys []string) {
relation = make(map[string][]Colours)
for _, rule := range input {
baseColour := strings.Join(rule[:2], " ")
relation[baseColour] = make([]Colours, 0)
keys = append(keys, baseColour)

...
}
return
}

然后使用这样生成的键来迭代映射。

底线是golang地图没有排序

最新更新