gpt4 book ai didi

string - 去比较字符串

转载 作者:IT王子 更新时间:2023-10-29 02:25:28 25 4
gpt4 key购买 nike

给定两个字符串 ab ,有时我想确定三个语句中的哪一个:a < b , a == ba > b是真的。

在像 C 或 C++ 这样的语言中,我会得到一个 int 值 v在调用相应的函数或方法后。然后我可以通过检查是否为 v < 0 来确定以上哪些说法是正确的, v == 0v > 0 .

但在 Go 中,我必须至少进行两次比较(例如,首先测试 a < b,然后测试 a == b)以找出三个语句中哪一个是正确的。

我的问题是 Go 中是否有一种方法可以让我只进行一次比较?

原来这个特征叫做three way comparison .

最佳答案

即使这个比较器函数存在于 strings 包 ( strings.Compare() ) 中,甚至它的文档也建议不要使用它:

Compare returns an integer comparing two strings lexicographically. The result will be 0 if a==b, -1 if a < b, and +1 if a > b.

Compare is included only for symmetry with package bytes. It is usually clearer and always faster to use the built-in string comparison operators ==, <, >, and so on.

为什么使用 strings.Compare() 不切实际?

有几个原因。

首先,在这种 Compare() 实用/常见的语言中,通常这些语言支持完全基于具有此签名的函数构建的排序。

例如,在 Java 中有 Comparator 接口(interface),您可以将其传递给 Collections.sort() 。因此,在 Java 中,您被迫拥有/实现这种比较(返回 -101 )。

在 Go 中,排序不是基于这样的比较函数。在 Go 中,排序是基于单个 Less(i, j int) bool 函数,它基本上是 a[i] < a[j] 比较,只是“是不是少了?”。为此,您不需要 strings.Compare() ,您只需要 a < b 。例如,请参见 sort.Slice()

第二个原因:strings.Compare()有意优化,因此您不习惯使用它。 strings.Compare() 的实现有这样的注释:

// NOTE(rsc): This function does NOT call the runtime cmpstring function,
// because we do not want to provide any performance justification for
// using strings.Compare. Basically no one should use strings.Compare.
// As the comment above says, it is here only for symmetry with package bytes.
// If performance is important, the compiler should be changed to recognize
// the pattern so that all code doing three-way comparisons, not just code
// using strings.Compare, can benefit.

这意味着 a < b 将比调用 strings.Compare(a, b) 更快。

第三,strings.Compare()的返回值是一个整数,携带a是否小于b,或者a是否等于b,或者a是否大于b的信息。如果您确实需要使用所有 3 个分支(不仅仅是“less”或“equal”分支),您通常需要对 strings.Compare() 的返回值做进一步检查,就像这个简单的例子:

switch strings.Compare("a", "b") {
case -1:
fmt.Println("less")
case 0:
fmt.Println("equal")
case 1: // or default:
fmt.Println("greater")
}

现在,如果您考虑一下:比较首先在 strings.Compare() 内部执行,然后在您的代码中再次执行(比较返回值)。这是多余的,而且性能也很差。

上面可以这样写(这样会更快):

switch {
case a == b:
fmt.Println("equal")
case a < b:
fmt.Println("less")
default:
fmt.Println("greater")
}

关于效率的更多信息

如前所述,strings.Compare() 并未有意针对性能进行优化。但是Go的排序库不需要-101结果对字符串进行排序,只需要a < b的结果,可以和其他语言获取Compare()的结果一样高效。

另请注意,strings.Compare() 首先检查 a == b 是否相等,只有当它们不相等时才继续检查 a < b。这很重要,因为 Go 中的 string 值存储了 string 的长度(详细信息,请参见 reflect.StringHeader ),这意味着如果 2 个字符串的长度不同,可以立即判断它们不相等。 C 和 C++ 使用以 \0 结尾的字符串值,这意味着判断 2 个字符串是否相等总是需要比较整个字符串,即使一个是一千个字符而另一个是少一个。实际上这并不完全正确,因为如果在比较字符时检测到不匹配,则比较结束,但这可能仍然比比较 2 个整数慢很多。

另见相关问题:Using the == symbol in golang and using a loop to compare if string a equals string b,which performance is better?

关于string - 去比较字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52830314/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com