在Golang中查找最长单词

5

尝试使用Go语言从句子中找到最长的单词。

目前我正在使用以下方法:

func longestWord(s string) string {

    newArr := strings.Split(s, " ")

    l := len(newArr[0])
    long := newArr[0]
    var result string
    // fmt.Println(long)
    for _, lenString := range newArr {

        if len(lenString) > l {
            // ll := len(lenString)
            // l := len(lenString)
            d := &l
            p := &long
            c := &result
            *d = len(lenString)
            *p = lenString
            *c = lenString
            // fmt.Println(lenString)
        } else {
            c := &result
            *c = newArr[0]
        }

    }
    return result
}

func main() {
    args := "Monday Tuesday Friday Sunday Wednesday"
    fmt.Println(longestWord(args))
}

但我不确定这是实现它的最佳方法。是否有其他更优雅的方法?我知道还有一种使用排序的方法,但我更喜欢使用单词之间的迭代方式。


1
注意:在字符串范围内,将会涵盖字节数量,这并不总是等同于字符数量(“Hi”长度为2个字节而“世界”长度为6个字节)。要涵盖字符数,请使用“i,c:= range []rune(str)”。如果您的最终输出目标是终端,请考虑使用[go-runewidth](https://github.com/mattn/go-runewidth)来测量等宽字符的宽度。 - Roshambo
3个回答

7

“最佳”解决方案

我们可以利用以下方法,使代码比其他答案更加简洁:

  • 使用元组赋值
  • best及其长度初始化为零值(""0),并省略对0个单词的检查,因为for range循环会正确处理
  • 不需要将words存储为本地变量,因为它仅在循环中使用

这样做不会影响代码的可读性:

func longestWord(s string) string {
    best, length := "", 0
    for _, word := range strings.Split(s, " ") {
        if len(word) > length {
            best, length = word, len(word)
        }
    }
    return best
}

测试一下:

fmt.Printf("%q\n", longestWord(""))
args := "Monday Tuesday Friday Sunday Wednesday"
fmt.Printf("%q\n", longestWord(args))

输出结果(请在Go Playground上尝试):

""
"Wednesday"

最紧凑的解决方案

需要注意的是,存储best的长度是可选的,纯粹是为了优化目的,因为如果我们有best,它的长度总是len(best)

利用这一点,以及我们可以使用命名结果参数(并且所有变量除非提供初始值,否则都会初始化为其类型的零值,对于string来说是""),我们甚至可以更加紧凑地编写它,不会损失可读性:

func longestWord(s string) (best string) {
    for _, word := range strings.Split(s, " ") {
        if len(word) > len(best) {
            best = word
        }
    }
    return
}

测试和输出是相同的,可在Go Playground上尝试。 在大多数情况下,与我们也存储长度时相比,这可能略微较慢。


4

这完全可行!你可以将其缩短一些,同时使用更长的变量名来更好地解释你的意图。

func longestWord(s string) string {
    words := strings.Split(s, " ")
    if len(words) == 0 {
        return ""
    }
    best := words[0]
    best_length := 0
    for _, word := range words {
        if len(word) > best_length {
            best = word
            best_length = len(word)
        }
    }
    return best
}

如果您愿意,可以将此更改为跟踪指针而不是单词本身。


1
我会这样做:

func longestWord(s string) string {

newArr := strings.Split(s, " ")

longestWord := ""
longestLength := 0

    // loop through the array
    for _, word := range newArr {
        // save length of word in the actual iteration
        length := len(word)

        // if length is larger, than longest
        if length > longestLength {
            // save the new longest word
            longestWord = word
            longestLength = length
        }
    }


// return the longest word
return longestWord
}

实现可在go playground中找到。


1
不需要检查数组是否为空(if len(newArr)>0),因为在这种情况下,范围循环就不会执行。换句话说,在空数组上进行范围循环是安全的。 - ain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接