本文介紹了go在字元方面的一些處理技巧,比如使用位元組32異或實現大小寫轉換,以及二進位制狀態序列
題面
給定一個字串S
,通過將字串S
中的每個字母轉變大小寫,我們可以獲得一個新的字串。返回所有可能得到的字串集合。
示例:
輸入:S = "a1b2"
輸出:["a1b2", "a1B2", "A1b2", "A1B2"]
S 的長度不超過12。
S 僅由數字和字母組成。
來源:力扣(LeetCode)
連結:leetcode-cn.com/problems/letter-ca...
分析
- 序列每個字元位置不發生變換,只是字母大小有改變
- 字母大小寫轉換前後兩個狀態,可以用二進位制數0與1表示
- 假定初始串
abca
表示為0000
二進位制狀態數,那麼0100
則表示串aBca
- 換而言之,可用二進位制數
0 - 1111
表示abca
所有字母大小寫轉換全排列
位運算
func letterCasePermutation(S string) []string {
N := len(S)
rs := []string{S}
// 字母轉換後的狀態表
m := make(map[int]byte,0)
// 提取字母大小寫轉化後的1值狀態表
for i:=0;i< N;i++ {
if num := int(S[i] - '0'); num > 9 {
m[i]= translate(S[i]) // 或 S[i]^32
}
}
// 字母大小寫轉換全排列 產生的個數(如二進位制數 0 至 111 產生2的3次冪全排列數)
binary := int(math.Pow(2,float64(len(m))))
for k:=1;k < binary;k++ {
s := []byte(S) // 維護大小寫轉換前狀態
for i,j:=N-1,k;i>=0;i-- {
if v, ok := m[i];ok {
if j % 2 != 0 { // 狀態1轉換大小,狀態0不轉
s[i] = v
}
j>>=1 // 右移,以便下次獲取低位值
if j == 0 {
break // 已至最高位跳出
}
}
}
rs = append(rs, string(s))
}
return rs
}
大小寫轉換
- 查表可知字母a 97, A 65, 空格 32
byte
實際是uint
型別的別名,因此可進行運算
其實,還有一個裝逼方法, 將大小寫字母與 32 進行異或運算,如下func translate(b byte) byte { if b >= 'a' { return b - ' ' } return b + ' ' }
a := uint(97) A := uint(65) fmt.Println(string(a),string(A),string(a^32),string(A^32)) // 輸出 a A A a
本作品採用《CC 協議》,轉載必須註明作者和本文連結