我在 Hackerrank 上做一個練習,在討論中我偶然發現了一個非常好的單行解決方案來解決以下問題:
S 是一個字母數字字串,您必須使用以下規則對其進行排序:
- 所有排序的小寫字母都在大寫字母之前。
- 所有排序的大寫字母都在數字之前。
- 所有已排序的奇數位都在已排序的偶數位之前。
提供的解決方案是:
print(*sorted(input(), key=lambda c: (-ord(c) >> 5, c in '02468', c)), sep='')
現在,我了解了 lambda 是如何作業的以及 ord 是如何作業的,我想正確理解這段代碼,所以這是我為理解它所做的:
b = "Sorting1234"
print(*sorted(input(), key=lambda c: (ord(c))), sep='')
輸出:
['1', '2', '3', '4', 'S', 'g', 'i', 'n', 'o', 'r', 't']
因此,此代碼根據 ASCII 代碼對給定字串進行排序。現在,我們希望先是小寫字母,然后是大寫字母,然后是數字,所以我們現在顛倒這個順序:
sorted(b,key=lambda x: (-ord(x)))
輸出:
['t', 'r', 'o', 'n', 'i', 'g', 'S', '4', '3', '2', '1']
現在,這部分我不明白,為什么我們使用二進制移位運算子,它有什么用途?
sorted(b,key=lambda x: (-ord(x)>>3))
輸出:
['r', 't', 'o', 'i', 'n', 'g', 'S', '1', '2', '3', '4']
現在右移 5:
sorted(b,key=lambda x: (-ord(x)>>5))
輸出:
['o', 'r', 't', 'i', 'n', 'g', 'S', '1', '2', '3', '4']
我們甚至還沒有達到我們實際想要的一半,但是完整的代碼突然產生了正確的答案:
sorted(b,key=lambda x: (-ord(x)>>5, x in '02467', x))
輸出:
['g', 'i', 'n', 'o', 'r', 't', 'S', '1', '3', '2', '4']
uj5u.com熱心網友回復:
看 ASCII 表,128 個字符排列成四列,每列 32 個(這里只顯示可列印的字符):
0 32 64 @ 96 `
1 33 ! 65 A 97 a
2 34 " 66 B 98 b
3 35 # 67 C 99 c
4 36 $ 68 D 100 d
5 37 % 69 E 101 e
6 38 & 70 F 102 f
7 39 ' 71 G 103 g
8 40 ( 72 H 104 h
9 41 ) 73 I 105 i
10 42 * 74 J 106 j
11 43 75 K 107 k
12 44 , 76 L 108 l
13 45 - 77 M 109 m
14 46 . 78 N 110 n
15 47 / 79 O 111 o
16 48 0 80 P 112 p
17 49 1 81 Q 113 q
18 50 2 82 R 114 r
19 51 3 83 S 115 s
20 52 4 84 T 116 t
21 53 5 85 U 117 u
22 54 6 86 V 118 v
23 55 7 87 W 119 w
24 56 8 88 X 120 x
25 57 9 89 Y 121 y
26 58 : 90 Z 122 z
27 59 ; 91 [ 123 {
28 60 < 92 \ 124 |
29 61 = 93 ] 125 }
30 62 > 94 ^ 126 ~
31 63 ? 95 _ 127
對 0 到 3 列進行編號,您將在第 1 列中找到數字,在第 2 列中找到大寫字母,在第 3 列中找到小寫字母。
右移 5 相當于除以 32 并向下舍入。所以ord(c) >> 5會給你列號 1、2 或 3,具體取決于型別數字/上/下。因為我們想要相反的順序,所以我們否定。
實際的運算式首先-ord(c) >> 5取反(如空格所示),這稍微改變了一些情況:第一行??(代碼為0、32、64和 96 的字母)得到了錯誤的列號。但這些角色對我們來說無關緊要。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/437143.html
