概述
Swift 语言是一门现代化、安全、强大且还算性感的语言。在去年 WWDC 24 中苹果正式推出了秃头码农们期待许久的 Swift 6.0,它进一步完善了 Swift 语言的语法和语义,并再接再厉------强化了现代化并发模型的安全性和灵活性。
这里我们不妨用 Swift 来验证一个实际世界中有趣的小疑问:汉语中到底有没有拼音首字母全部相同的 4 字成语呢?
在本篇博文中,您将学到如下内容:
到底问题的谜底将会如何?结果绝对会让大家"始料不及"!
那还等什么呢?Let's go!!!😉
8. 枝节横生
不过先别忙,因为忙中会出错!
使用上面的逻辑会找出很多只有 1 个拼音的 4 字(或 4 字以上)的成语,这是怎么回事呢?
重厚寡言 (zhòng hòu guǎ yán),拼音个数: 1
质而不野 (zhì ér bù yě),拼音个数: 1
蒸沙为饭 (zhēng shā wéi fàn),拼音个数: 1
引吭高声(yǐn háng gāo shēng),拼音个数: 1
一朝千里(yī zhāo qiān lǐ),拼音个数: 1
一朝之患(yī zhāo zhī huàn),拼音个数: 1
悬车之年(xuán chē zhī nián),拼音个数: 1
悬崖绝壁(xuán yá jué bì),拼音个数: 1
休明盛世(xiū míng shèng shì),拼音个数: 1
修旧利废(xiū jiù lì fèi),拼音个数: 1
项庄舞剑,志在沛公(xiàng zhuāng wǔ jiàn,zhì zài pèi gōng),拼音个数: 1
橡茹藿歠(xiàng rú huò chuò),拼音个数: 1
同文共轨(tóng wén gòng guǐ),拼音个数: 1
水长船高(shuǐ zhǎng chuán gāo),拼音个数: 1
书不尽言(shū bù jìn yán),拼音个数: 1
情长纸短(qíng cháng zhǐ duǎn),拼音个数: 1
弃书捐剑(qì shū juān jiàn),拼音个数: 1
批亢抵巇(pī gāng dǐ xī),拼音个数: 1
泥古拘方(nì gǔ jū fāng),拼音个数: 1
泥名失实(nì míng shī shí),拼音个数: 1
风轻云淡(fēng qīng yún dàn),拼音个数: 1
粉骨捐躯(fěn gǔ juān qū),拼音个数: 1
粉骨糜躯(fěn gǔ mí qū),拼音个数: 1
粉面朱唇(fěn miàn zhū chún),拼音个数: 1
粉身灰骨(fěn shēn huī gǔ),拼音个数: 1
堤溃蚁孔(dī kuì yǐ kǒng),拼音个数: 1
沉厚寡言(chén hòu guǎ yán),拼音个数: 1
沉重寡言(chén zhòng guǎ yán),拼音个数: 1
长幼有序(zhǎng yòu yǒu xù),拼音个数: 1
可以看到,这些成语至少都包含 4 个字,但为什么对应的拼音却只有 1 个呢?
这是由于这些成语拼音的间隔都不是普通的空格,而是其它字符导致的。仔细检查可以发现,这里实际间隔字符序列二进制值为 0xe3、0x80、0x80(即 8 位整形数组[227, 128, 128])。
有的小伙伴们可能又会问了:你是怎么知道这些特殊"空格"编码实际二进制值的?很简单,我们做实验!
swift
if pinyins.count == 1 {
print("找到拼音间隔不为简单空格(0x20): \(pinyins)")
let cString = idiomPinyin.cString(using: .utf8)!
for (i,cchar) in cString.enumerated() {
print("[\(i)]: \(String.init(format: "%02x", cchar))")
}
break
}
我们在上面的代码里将原字符串先转换为 C 字符串,然后打印出每个字符的字节码一窥究竟:
找到拼音间隔不为简单空格(0x20): ["zhòng hòu guǎ yán"]
[0]: 7a
[1]: 68
[2]: ffffffc3
[3]: ffffffb2
[4]: 6e
[5]: 67
[6]: ffffffe3
[7]: ffffff80
[8]: ffffff80
[9]: 68
[10]: ffffffc3
[11]: ffffffb2
[12]: 75
[13]: ffffffe3
[14]: ffffff80
[15]: ffffff80
[16]: 67
[17]: 75
[18]: ffffffc7
[19]: ffffff8e
[20]: ffffffe3
[21]: ffffff80
[22]: ffffff80
[23]: 79
[24]: ffffffc3
[25]: ffffffa1
[26]: 6e
[27]: 00
经过与原字符串中的字符对比,我们可以轻松求出间隔字符的编码为:0xe3,0x80,0x80。
一种方法是将它们替换为普通的空格字符(0x20),然后再解析:
swift
let pinyins = idiomPinyin.split(separator: " ")
if pinyins.count == 1 {
print("找到拼音间隔不为简单空格(0x20): \(pinyins)")
let pyData = idiomPinyin.data(using: .utf8)!
let fixedData = pyData.replacing([227,128,128], with: [32])
let fixedPyString = String(data: fixedData, encoding: .utf8)!
let fixedPy = fixedPyString.split(separator: " ")
print("FIXED![\(fixedPy.count)]: \(fixedPy)")
}
运行可以发现,我们又可以成功的找回这些成语的所有拼音啦:
找到拼音间隔不为简单空格(0x20): ["zhòng hòu guǎ yán"]
FIXED![4]: ["zhòng", "hòu", "guǎ", "yán"]
找到拼音间隔不为简单空格(0x20): ["zhì ér bù yě"]
FIXED![4]: ["zhì", "ér", "bù", "yě"]
找到拼音间隔不为简单空格(0x20): ["zhēng shā wéi fàn"]
FIXED![4]: ["zhēng", "shā", "wéi", "fàn"]
找到拼音间隔不为简单空格(0x20): ["yǐn háng gāo shēng"]
FIXED![4]: ["yǐn", "háng", "gāo", "shēng"]
找到拼音间隔不为简单空格(0x20): ["yī zhāo qiān lǐ"]
FIXED![4]: ["yī", "zhāo", "qiān", "lǐ"]
找到拼音间隔不为简单空格(0x20): ["yī zhāo zhī huàn"]
FIXED![4]: ["yī", "zhāo", "zhī", "huàn"]
找到拼音间隔不为简单空格(0x20): ["xuán chē zhī nián"]
FIXED![4]: ["xuán", "chē", "zhī", "nián"]
找到拼音间隔不为简单空格(0x20): ["xuán yá jué bì"]
FIXED![4]: ["xuán", "yá", "jué", "bì"]
...
9. 尘埃落定
转眼之间这些"难关"都被逐一攻克,我们离最后的胜利只差一步之遥。
接下来我们只需获取所有拼音的首字母,然后判断它们是否相等即可。简单的方法是用集合(Set)的唯一性来解决它:
swift
var pinyinFirstChars = pinyins.map { $0.first! }
if Set(pinyinFirstChars).count == 1 {
// 若所有拼音首字母相同,则集合里只会留存 1 个元素!
}
现在,我们可以怡然自得的补全代码中最后一块拼图了:
swift
var bingooCount = 0
let pinyins = idiomPinyin.split(separator: " ")
var pinyinFirstChars = pinyins.map { $0.first! }
if pinyins.count == 1 {
print("找到拼音间隔不为简单空格(0x20): \(pinyins)")
let pyData = idiomPinyin.data(using: .utf8)!
let fixedData = pyData.replacing([227,128,128], with: [32])
let fixedPyString = String(data: fixedData, encoding: .utf8)!
let fixedPy = fixedPyString.split(separator: " ")
print("FIXED![\(fixedPy.count)]: \(fixedPy)")
pinyinFirstChars = fixedPy.map { $0.first! }
}
if Set(pinyinFirstChars).count == 1 {
bingooCount += 1
print("[\(bingooCount)]BINGOOO: \(idiomName)(\(idiomPinyin)) - \(pinyinFirstChars)")
}
10. "超乎想象"的结果
运行代码,大家猜猜在这 3w+ 条成语中到底有多少个首字母完全相同的成语呢?
除去疑似重复的成语,我们一共找到了 38 个符合条件的成语:
[1]: 做张做致 (zuò zhāng zuò zhì) - ["z", "z", "z", "z"]
[2]: 做张做智 (zuò zhāng zuò zhì) - ["z", "z", "z", "z"]
[3]: 自作主张 (zì zuò zhǔ zhāng) - ["z", "z", "z", "z"]
[4]: 捉贼捉赃 (zhuō zéi zhuō zāng) - ["z", "z", "z", "z"]
[5]: 捉贼捉脏 (zhuō zéi zhuō zāng) - ["z", "z", "z", "z"]
[6]: 知足知止 (zhī zú zhī zhǐ) - ["z", "z", "z", "z"]
[7]: 真赃真贼 (zhēn zāng zhēn zéi) - ["z", "z", "z", "z"]
[8]: 隐隐约约(yǐn yǐn yuē yuē) - ["y", "y", "y", "y"]
[9]: 遗音余韵(yí yīn yú yùn) - ["y", "y", "y", "y"]
[10]: 一吟一咏(yī yīn yī yǒng) - ["y", "y", "y", "y"]
[11]: 燕燕莺莺(yàn yàn yīng yīng) - ["y", "y", "y", "y"]
[12]: 惺惺惜惺(xīng xīng xī xīng) - ["x", "x", "x", "x"]
[13]: 惺惺相惜(xīng xīng xiāng xī) - ["x", "x", "x", "x"]
[14]: 伈伈睍睍(xǐn xǐn xiàn xiàn) - ["x", "x", "x", "x"]
[15]: 吞吞吐吐(tūn tūn tǔ tǔ) - ["t", "t", "t", "t"]
[16]: 忑忑忐忐(tè tè tǎn tǎn) - ["t", "t", "t", "t"]
[17]: 忐忐忑忑(tǎn tǎn tè tè) - ["t", "t", "t", "t"]
[18]: 顺时随俗(shùn shí suí sú) - ["s", "s", "s", "s"]
[19]: 适俗随时(shì sú suí shí) - ["s", "s", "s", "s"]
[20]: 生生世世(shēng shēng shì shì) - ["s", "s", "s", "s"]
[21]: 生生死死(shēng shēng sǐ sǐ) - ["s", "s", "s", "s"]
[22]: 三三四四(sān sān sì sì) - ["s", "s", "s", "s"]
[23]: 扭扭捏捏(niǔ niǔ niē niē) - ["n", "n", "n", "n"]
[24]: 袅袅娜娜(niǎo niǎo nuó nuó) - ["n", "n", "n", "n"]
[25]: 渺渺茫茫(miǎo miǎo máng máng) - ["m", "m", "m", "m"]
[26]: 历历落落(lì lì luò luò) - ["l", "l", "l", "l"]
[27]: 磊磊落落(lěi lěi luò luò) - ["l", "l", "l", "l"]
[28]: 屦及剑及(jù jí jiàn jí) - ["j", "j", "j", "j"]
[29]: 斤斤计较(jīn jīn jì jiào) - ["j", "j", "j", "j"]
[30]: 将计就计(jiāng jì jiù jì) - ["j", "j", "j", "j"]
[31]: 剑及屦及(jiàn jí jù jí) - ["j", "j", "j", "j"]
[32]: 将机就机(jiāng jī jiù jī) - ["j", "j", "j", "j"]
[33]: 将机就计(jiāng jī jiù jì) - ["j", "j", "j", "j"]
[34]: 驾肩接迹(jià jiān jiē jì) - ["j", "j", "j", "j"]
[35]: 昏昏浩浩(hūn hūn hào hào) - ["h", "h", "h", "h"]
[36]: 贩夫贩妇(fàn fū fàn fù) - ["f", "f", "f", "f"]
[37]: 颠颠倒倒(diān diān dǎo dǎo) - ["d", "d", "d", "d"]
[38]: 啛啛喳喳(cuì cuì chā chā) - ["c", "c", "c", "c"]
看来我大中华成语文化真乃泛浩摩苍,竟然有这么多读起来朗朗上口的成语,呜呼快哉,棒棒哒!
这个结果小伙伴们之前想到了吗?大家还能找到其它拼音首字母完全相同的 4 字成语吗?如果有请大家在文后恣意砌楼给我们意外惊喜。
至此,我们已经完全解决了博文开头那个问题!小伙伴们赶快给自己一个大大的赞吧!么么哒!😘
想要进一步系统地学习 Swift 开发的小伙伴们,可以来我的《Swift 语言开发精讲》专栏逛一逛哦:
总结
在本篇博文中,我们为 Swift 语言实现查找拼音首字母全部相同的 4 字成语这个小任务画上了一个完美的句号,很赞哦!
感谢观赏,再会啦!😎