From 4e515e9bd530b3b6d5725bf8cb2024124e4171d1 Mon Sep 17 00:00:00 2001 From: Marcel Edmund Franke Date: Sat, 2 Mar 2024 15:35:19 +0100 Subject: [PATCH] Strutil: HammingDistance func The Hamming distance is the number of positions at which the corresponding symbols are different --- strutil/string.go | 22 ++++++++++++++++++++++ strutil/string_example_test.go | 13 +++++++++++++ strutil/string_test.go | 23 +++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/strutil/string.go b/strutil/string.go index b8785fa..9aa423f 100644 --- a/strutil/string.go +++ b/strutil/string.go @@ -4,6 +4,7 @@ package strutil import ( + "errors" "regexp" "strings" "unicode" @@ -594,3 +595,24 @@ func SubInBetween(str string, start string, end string) string { return "" } + +// HammingDistance calculates the Hamming distance between two strings. +// The Hamming distance is the number of positions at which the corresponding symbols are different. +// This func returns an error if the input strings are of unequal lengths. +func HammingDistance(a, b string) (int, error) { + if len(a) != len(b) { + return -1, errors.New("a length and b length are unequal") + } + + ar := []rune(a) + br := []rune(b) + + var distance int + for i, codepoint := range ar { + if codepoint != br[i] { + distance++ + } + } + + return distance, nil +} diff --git a/strutil/string_example_test.go b/strutil/string_example_test.go index 54adfda..a9bcb28 100644 --- a/strutil/string_example_test.go +++ b/strutil/string_example_test.go @@ -667,3 +667,16 @@ func ExampleSubInBetween() { // abc // bc } + +func ExampleHammingDistance() { + + result, _ := HammingDistance("abc", "def") + fmt.Println(result) + + result, _ = HammingDistance("name", "namf") + fmt.Println(result) + + // Output: + // 3 + // 1 +} diff --git a/strutil/string_test.go b/strutil/string_test.go index 10c6135..3d94af0 100644 --- a/strutil/string_test.go +++ b/strutil/string_test.go @@ -581,3 +581,26 @@ func TestSubInBetween(t *testing.T) { assert.Equal("", SubInBetween(str, "a", "")) assert.Equal("", SubInBetween(str, "a", "f")) } + +func TestHammingDistance(t *testing.T) { + assert := internal.NewAssert(t, "HammingDistance") + + hd := func(a, b string) int { + c, _ := HammingDistance(a, b) + return c + } + + assert.Equal(0, hd(" ", " ")) + assert.Equal(1, hd(" ", "c")) + assert.Equal(1, hd("a", "d")) + assert.Equal(1, hd("a", " ")) + assert.Equal(1, hd("a", "f")) + + assert.Equal(0, hd("", "")) + assert.Equal(-1, hd("abc", "ab")) + assert.Equal(3, hd("abc", "def")) + assert.Equal(-1, hd("kitten", "sitting")) + assert.Equal(1, hd("ö", "ü")) + assert.Equal(0, hd("日本語", "日本語")) + assert.Equal(3, hd("日本語", "語日本")) +}