亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

去比較字符串

去比較字符串

Go
元芳怎么了 2023-04-24 16:18:24
給定兩個字符串a和b,有時我想確定三個語句中的哪一個:a < b, a == bora > b為真。在像 C 或 C++ 這樣的語言中,我會v在調用相應的函數或方法后得到一個 int 值。v < 0然后我可以通過檢查是否,v == 0或 來確定以上哪些陳述是正確的v > 0。但在 Go 中,我必須至少進行兩次比較(例如,先 testa < b然后 test a == b)才能找出三個語句中哪一個是正確的。我的問題是 Go 中是否有一種方法可以讓我只進行一次比較?事實證明,此功能稱為三向比較。
查看完整描述

3 回答

?
牛魔王的故事

TA貢獻1830條經驗 獲得超3個贊

盡管這個比較器函數存在于strings包 (?strings.Compare()) 中,但它的文檔也建議不要使用它:

Compare 返回一個按字典順序比較兩個字符串的整數。如果 a==b,結果將為 0,如果 a < b,則結果為 -1,如果 a > b,則結果為 +1。

包含比較只是為了與包字節對稱。使用內置的字符串比較運算符 ==、<、> 等通常更清晰、更快。

為什么不實用strings.Compare()?

有幾個原因。

首先,在這種Compare()實用/常見的語言中,通常這些語言支持完全基于具有此簽名的函數的排序。

例如,在 Java 中有一個Comparator接口,您可以將其傳遞給Collections.sort().?因此,在 Java 中,您被迫擁有/實現這種比較(返回-1,01)。

在 Go 中,排序不是基于這樣的比較函數。在 Go 中,排序是基于一個Less(i, j int) bool基本比較的函數a[i] < a[j],它只是“是不是少了?”。為此,你不需要strings.Compare(),你只需要a < b。

第二個原因: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的排序庫不需要-1,?0,1對字符串進行排序的結果,只需要 , 的結果a < b即可,獲取效率與Compare()其他語言獲取 的結果一樣。

還要注意,strings.Compare()首先檢查是否相等a == b,只有當它們不相等時才進行檢查a < b。這一點很重要,因為stringGo 中的值存儲了 the 的長度string,這意味著如果 2 個字符串的長度不同,則可以立即確定它們不相等。C 和 C++ 使用\0以 - 結尾的字符串值,這意味著判斷 2 個字符串是否相等總是需要比較整個字符串,即使一個是一千個字符而另一個是少一個。實際上這并不完全正確,因為如果在比較字符時檢測到不匹配,則比較結束,但這可能仍然比比較 2 個整數慢很多。


查看完整回答
反對 回復 2023-04-24
?
慕婉清6462132

TA貢獻1804條經驗 獲得超2個贊

Go 是由程序員為程序員設計的。如果你想要一個 Cstrcmp函數,用 Go 寫一個。


例如,


package main


import "fmt"


func strcmp(s1, s2 string) int {

? ? lens := len(s1)

? ? if lens > len(s2) {

? ? ? ? lens = len(s2)

? ? }

? ? for i := 0; i < lens; i++ {

? ? ? ? if s1[i] != s2[i] {

? ? ? ? ? ? return int(s1[i]) - int(s2[i])

? ? ? ? }

? ? }

? ? return len(s1) - len(s2)

}


func main() {

? ? tests := []struct {

? ? ? ? s1, s2 string

? ? ? ? cmp? ? int

? ? }{

? ? ? ? {"", "", 0},

? ? ? ? {"a", "a", 0},

? ? ? ? {"a", "b", -1},

? ? ? ? {"b", "a", +1},

? ? ? ? {"a", "aa", -1},

? ? ? ? {"aa", "a", 1},

? ? }

? ? for _, t := range tests {

? ? ? ? cmp := strcmp(t.s1, t.s2)

? ? ? ? fmt.Printf("%q %q %d %t\n", t.s1, t.s2, cmp, cmp == t.cmp)

? ? }

}

輸出:


"" "" 0 true

"a" "a" 0 true

"a" "b" -1 true

"b" "a" 1 true

"a" "aa" -1 true

"aa" "a" 1 true

GNU C 庫 (glibc):strcmp.c


查看完整回答
反對 回復 2023-04-24
?
慕的地10843

TA貢獻1785條經驗 獲得超8個贊

在沒有附加函數的情況下比較字符串在 Go 中就像一個魅力:


log.Println("as" > "ab") // true

log.Println("ab" == "ab") // true

log.Println("abc" < "abd") // true

回答您的問題:如果您想使用任何類型的函數(例如strings.Compare),那么您將獲得一個具有三種狀態的變量(即-1, 0, 1),最終您將不得不比較這三種狀態。因此,當我們談論字符串比較時,您無法避免比較少于兩次。


查看完整回答
反對 回復 2023-04-24
  • 3 回答
  • 0 關注
  • 168 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號