How to compare strings in golang? [closed]

2019-04-03 01:29发布

I want to make a function that calculates the length of the common segment (starting from the beginning) in two strings. For example:

foo:="Makan"
bar:="Makon"

The result should be 3.

foo:="Indah"
bar:="Ihkasyandehlo"

The result should be 1.

3条回答
该账号已被封号
2楼-- · 2019-04-03 01:38

You mean like this. Please note, this will not handle UTF 8, only ascii.

package main

import (
    "fmt"
)

func equal(s1, s2 string) int {
    eq := 0
    if len(s1) > len(s2) {
        s1, s2 = s2, s1
    }
    for key, _ := range s1 {
        if s1[key] == s2[key] {
            eq++
        } else {
            break
        }
    }
    return eq
}

func main() {
    fmt.Println(equal("buzzfizz", "buzz"))
    fmt.Println(equal("Makan", "Makon"))
    fmt.Println(equal("Indah", "Ihkasyandehlo"))
}
查看更多
看我几分像从前
3楼-- · 2019-04-03 01:49

Note that if you were working with Unicode characters, the result could be quite different.
Try for instance using utf8.DecodeRuneInString().

See this example:

package main

import "fmt"
import "unicode/utf8"

func index(s1, s2 string) int {
    res := 0
    for i, w := 0, 0; i < len(s2); i += w {
        if i >= len(s1) {
            return res
        }
        runeValue1, width := utf8.DecodeRuneInString(s1[i:])
        runeValue2, width := utf8.DecodeRuneInString(s2[i:])
        if runeValue1 != runeValue2 {
            return res
        }
        if runeValue1 == utf8.RuneError || runeValue2 == utf8.RuneError {
            return res
        }
        w = width
        res = i + w
    }
    return res
}

func main() {
    foo := "日本本a語"
    bar := "日本本b語"
    fmt.Println(index(foo, bar))
    foo = "日本語"
    bar = "日otest"
    fmt.Println(index(foo, bar))
    foo = "\xF0"
    bar = "\xFF"
    fmt.Println(index(foo, bar))
}

Here, the result would be:

  • 9 (3 common runes of width '3')
  • 3 (1 rune of width '3')
  • 0 (invalid rune, meaning utf8.RuneError)
查看更多
等我变得足够好
4楼-- · 2019-04-03 01:56

It's not clear what you are asking because you limited your test cases to ASCII characters.
I've added a Unicode test case and I've included answers for bytes, runes, or both.

play.golang.org:

package main

import (
    "fmt"
    "unicode/utf8"
)

func commonBytes(s, t string) (bytes int) {
    if len(s) > len(t) {
        s, t = t, s
    }
    i := 0
    for ; i < len(s); i++ {
        if s[i] != t[i] {
            break
        }
    }
    return i
}

func commonRunes(s, t string) (runes int) {
    if len(s) > len(t) {
        s, t = t, s
    }
    i := 0
    for ; i < len(s); i++ {
        if s[i] != t[i] {
            break
        }
    }
    return utf8.RuneCountInString(s[:i])
}

func commonBytesRunes(s, t string) (bytes, runes int) {
    if len(s) > len(t) {
        s, t = t, s
    }
    i := 0
    for ; i < len(s); i++ {
        if s[i] != t[i] {
            break
        }
    }
    return i, utf8.RuneCountInString(s[:i])
}

func main() {
    Tests := []struct {
        word1, word2 string
    }{
        {"Makan", "Makon"},
        {"Indah", "Ihkasyandehlo"},
        {"日本語", "日本語"},
    }
    for _, test := range Tests {
        fmt.Println("Words:        ", test.word1, test.word2)
        fmt.Println("Bytes:        ", commonBytes(test.word1, test.word2))
        fmt.Println("Runes:        ", commonRunes(test.word1, test.word2))
        fmt.Print("Bytes & Runes: ")
        fmt.Println(commonBytesRunes(test.word1, test.word2))
    }
}

Output:

Words:         Makan Makon
Bytes:         3
Runes:         3
Bytes & Runes: 3 3
Words:         Indah Ihkasyandehlo
Bytes:         1
Runes:         1
Bytes & Runes: 1 1
Words:         日本語 日本語
Bytes:         9
Runes:         3
Bytes & Runes: 9 3
查看更多
登录 后发表回答