1

これはGoの単語カウント関数です

package wc

import (
    "regexp"
    "strings"
)

type Histogram map[string]int

func WordCount(input string) Histogram {
    histogram := make(map[string]int)
    re := regexp.MustCompile("[^a-zA-Z0-9 ]*")
    input = re.ReplaceAllString(input, "")

    for _, word := range strings.Split(input, " ") {
        if word == "" {
            continue
        }
        histogram[strings.ToLower(word)]++
    }

    return histogram
}

このコードは、非決定論的にテストに合格または不合格になります。予想されるマップと実際のマップが一致しないために失敗する場合がありました。ただし、両者の内容はまったく同じです。地図比較に問題があると思います。どうすれば修正できるかわかりません。誰か助けてください!

これがテストスイートのコードです

package wc

import (
    "fmt"
    "testing"
)

var testCases = []struct {
    description string
    input       string
    output      Histogram
}{
    {
        description: "a single word",
        input:       "word",
        output:      Histogram{"word": 1},
    },
    {
        description: "one of each",
        input:       "one of each",
        output:      Histogram{"one": 1, "of": 1, "each": 1},
    },
    {
        description: "multiple occurrences",
        input:       "one fish two fish red fish blue fish",
        output:      Histogram{"one": 1, "fish": 4, "two": 1, "red": 1, "blue": 1},
    },
    {
        description: "ignore punctuation",
        input:       "car : carpet as java : javascript!!&@$%^&",
        output:      Histogram{"car": 1, "carpet": 1, "as": 1, "java": 1, "javascript": 1},
    },
    {
        description: "including numbers",
        input:       "testing, 1, 2 testing",
        output:      Histogram{"testing": 2, "1": 1, "2": 1},
    },
    {
        description: "normalises case",
        input:       "go Go GO",
        output:      Histogram{"go": 3},
    },
}

func TestWordCount(t *testing.T) {
    for _, tt := range testCases {
        expected := fmt.Sprintf("%v", tt.output)
        actual := fmt.Sprintf("%v", WordCount(tt.input))

        if expected != actual {
            t.Fatalf("%s\n\tExpected: %v\n\tGot: %v", tt.description, expected, actual)
        } else {
            t.Logf("PASS: %s - WordCount(%s)", tt.description, tt.input)
        }
    }
}

以下に、障害状況の例を示します。

1.
Expected: map[two:1 red:1 blue:1 one:1 fish:4]
Got: map[one:1 fish:4 two:1 red:1 blue:1]
2.
Expected: map[one:1 fish:4 two:1 red:1 blue:1]
Got: map[red:1 blue:1 one:1 fish:4 two:1]
3.
Expected: map[java:1 javascript:1 car:1 carpet:1 as:1]
Got: map[javascript:1 car:1 carpet:1 as:1 java:1]
...

追加情報はこちら: http://exercism.io/submissions/cf94f4732fd97335be2e755f

4

2 に答える 2

3

You can't compare expected and actual with !=, because it compares the string representation of the maps, so it will work only randomly (if the values are printed in the same order).

What you have to do, is to use the reflect package DeepEqual() method to compare the maps :

import "reflect"
// ...

if !reflect.DeepEqual(tt.output, WordCount(tt.input)) {
// ...

It will first checks if both maps are nil, then if they have the same length, then if they have the same set of (key, value) pairs.

于 2014-02-13T05:28:46.987 に答える
2

2 つのマップを比較しているのではなく、2 つのマップの String() 出力を比較しています。ただし、マップを出力したり range() した場合、コンテンツはランダムに選択されるため、文字列と比較することはできません。

最初に長さを比較し、次にそれらの 1 つを range() して、最初のマップのすべてのキーの値が存在し、2 番目のマップの同じキーの値と等しいかどうかを確認できます。

于 2014-02-13T05:21:05.987 に答える