Swift 趣味开发:查找拼音首字母全部相同的 4 字成语(下)

概述

Swift 语言是一门现代化、安全、强大且还算性感的语言。在去年 WWDC 24 中苹果正式推出了秃头码农们期待许久的 Swift 6.0,它进一步完善了 Swift 语言的语法和语义,并再接再厉------强化了现代化并发模型的安全性和灵活性。

这里我们不妨用 Swift 来验证一个实际世界中有趣的小疑问:汉语中到底有没有拼音首字母全部相同的 4 字成语呢?

在本篇博文中,您将学到如下内容:

  • 概述
  • [8. 枝节横生](#8. 枝节横生)
  • [9. 尘埃落定](#9. 尘埃落定)
  • [10. "超乎想象"的结果](#10. “超乎想象”的结果)
  • 总结

到底问题的谜底将会如何?结果绝对会让大家"始料不及"!

那还等什么呢?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 字成语这个小任务画上了一个完美的句号,很赞哦!

感谢观赏,再会啦!😎

相关推荐
*TQK*17 分钟前
C++范围基 for 循环
java·开发语言
myshare202218 分钟前
Java开发提速秘籍:巧用Apache Commons Lang工具库
java·开发语言
小白的一叶扁舟31 分钟前
Go之Walk框架详解
开发语言·后端·信息可视化·golang
知星小度S41 分钟前
今天你学C++了吗?——C++中的STL
开发语言·c++
egekm_sefg1 小时前
【JSqlParser】Java使用JSqlParser解析SQL语句总结
java·开发语言·sql
WangMing_X2 小时前
C# 根据name查找并返回winform菜单栏(MenuStrip)、工具栏(ToolStrip)中的子控件来修改属性
开发语言·c#
Ai 编码助手3 小时前
高性能、并发安全的 Go 嵌入式缓存库 如何使用?
开发语言·缓存·golang
像污秽一样3 小时前
AI刷题-小R的随机播放顺序、不同整数的计数问题
开发语言·c++·算法
懒大王爱吃狼4 小时前
【数据分析与可视化】Python绘制数据地图-GeoPandas地图可视化
开发语言·python·学习·数据挖掘·数据分析·python基础·python学习
m0_748234084 小时前
差异基因富集分析(R语言——GO&KEGG&GSEA)
开发语言·golang·r语言