From 0b5e88437194b54fb4115d33a5857c830fb8760d Mon Sep 17 00:00:00 2001 From: donutloop Date: Sun, 3 Mar 2024 14:48:34 +0100 Subject: [PATCH] Strutil: HammingDistance func (#197) * Strutil: HammingDistance func The Hamming distance is the number of positions at which the corresponding symbols are different * Add hamming distance doc --- docs/api/packages/strutil.md | 33 ++++++++++++++++++++++++++++++++ docs/en/api/packages/strutil.md | 34 +++++++++++++++++++++++++++++++++ strutil/string.go | 22 +++++++++++++++++++++ strutil/string_example_test.go | 13 +++++++++++++ strutil/string_test.go | 23 ++++++++++++++++++++++ 5 files changed, 125 insertions(+) diff --git a/docs/api/packages/strutil.md b/docs/api/packages/strutil.md index c378ce6..909161d 100644 --- a/docs/api/packages/strutil.md +++ b/docs/api/packages/strutil.md @@ -61,6 +61,7 @@ import ( - [ContainsAny](#ContainsAny) - [RemoveWhiteSpace](#RemoveWhiteSpace) - [SubInBetween](#SubInBetween) +- [HammingDistance](#HammingDistance)
@@ -1495,4 +1496,36 @@ func main() { // abc // bc } +``` + +### HammingDistance + +

TBD

+ +函数签名: + +```go +HammingDistance(a, b string) (int, error) +``` + +示例: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + + result1, _ := strutil.HammingDistance("de", "de") + result2, _ := strutil.HammingDistance("a", "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // 1 +} ``` \ No newline at end of file diff --git a/docs/en/api/packages/strutil.md b/docs/en/api/packages/strutil.md index 2a5c1a5..b184c45 100644 --- a/docs/en/api/packages/strutil.md +++ b/docs/en/api/packages/strutil.md @@ -60,6 +60,8 @@ import ( - [ContainsAll](#ContainsAll) - [ContainsAny](#ContainsAny) - [RemoveWhiteSpace](#RemoveWhiteSpace) +- [SubInBetween](#SubInBetween) +- [HammingDistance](#HammingDistance)
@@ -1496,4 +1498,36 @@ func main() { // abc // bc } +``` + +### HammingDistance + +

HammingDistance calculates the Hamming distance between two strings. The Hamming distance is the number of positions at which the corresponding symbols are different

+ +Signature: + +```go +HammingDistance(a, b string) (int, error) +``` + +Example: + +```go +import ( + "fmt" + "github.com/duke-git/lancet/v2/strutil" +) + +func main() { + + result1, _ := strutil.HammingDistance("de", "de") + result2, _ := strutil.HammingDistance("a", "d") + + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 0 + // 1 +} ``` \ No newline at end of file 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("日本語", "語日本")) +}