1 回答

TA貢獻1818條經驗 獲得超8個贊
您只能使用make()
和new()
分配已清零的緩沖區(字節片或數組)。您可以使用復合文字來獲取最初包含非零值的切片或數組,但您不能動態描述初始值(索引必須是常量)。
從類似但非常有效的strings.Repeat()
函數中獲取靈感。它以給定的計數重復給定的字符串:
func Repeat(s string, count int) string {
? ? // Since we cannot return an error on overflow,
? ? // we should panic if the repeat will generate
? ? // an overflow.
? ? // See Issue golang.org/issue/16237
? ? if count < 0 {
? ? ? ? panic("strings: negative Repeat count")
? ? } else if count > 0 && len(s)*count/count != len(s) {
? ? ? ? panic("strings: Repeat count causes overflow")
? ? }
? ? b := make([]byte, len(s)*count)
? ? bp := copy(b, s)
? ? for bp < len(b) {
? ? ? ? copy(b[bp:], b[:bp])
? ? ? ? bp *= 2
? ? }
? ? return string(b)
}
strings.Repeat()
進行一次分配以獲得工作緩沖區(這將是一個字節 slice?[]byte
),并使用內置copy()
函數復制可重復的字符串。值得注意的一件事是它使用工作副本并嘗試逐步復制整個副本,這意味著例如如果字符串已被復制 4 次,則復制此緩沖區將使其成為 8 次,等等。這將最大限度地減少對copy()
.?該解決方案還利用了copy()
可以從 a 復制字節string
而無需將其轉換為字節片的優勢。
我們想要的是類似的東西,但我們希望將結果添加到字符串之前。
我們可以考慮到這一點,只需分配一個內部使用的緩沖區Repeat()
加上我們左填充的字符串的長度。
結果(不檢查參數count
):
func PadLeft(s, p string, count int) string {
? ? ret := make([]byte, len(p)*count+len(s))
? ? b := ret[:len(p)*count]
? ? bp := copy(b, p)
? ? for bp < len(b) {
? ? ? ? copy(b[bp:], b[:bp])
? ? ? ? bp *= 2
? ? }
? ? copy(ret[len(b):], s)
? ? return string(ret)
}
測試它:
fmt.Println(PadLeft("aa", "x", 1))
fmt.Println(PadLeft("aa", "x", 2))
fmt.Println(PadLeft("abc", "xy", 3))
輸出(在Go Playground上嘗試):
xaa
xxaa
xyxyxyabc
- 1 回答
- 0 關注
- 148 瀏覽
添加回答
舉報