初探编码的世界,Ruby 30 天刷题修行篇第六话

大家好,我是 A Fei,今天是连假最後一天,虽然正在忙转职根本没有放假的感觉,但看到手机里亲友们一些祝福的话,还是蛮窝心的,希望明天转职成功後再跟大夥一起烤肉、喝酒,也希望疫情赶快结束。

今天我们要做的题目跟编码有关,话说很久很久以前,电脑刚起步的时代,ASCII 作为最早的编码语言,主要显示的语言仅限於英文字母,1986 年最後一次更新时共定义了 128 个字元,但人们很快就发现 128 个字元根本不够用,而且对其他语言使用者根本不公平,於是又有了 EASCII 支援其他西欧国家语言。随着电脑普及,万国码 Unicode 被制定了出来了,2021 年 9 月公布的最新版本,当中已经收录超过 14 万个字元,是现在全球最泛用的电脑编码。(如果有讲错或遗漏还望读者指正)

科普时间结束,让我们直接看看今天的题目:
(题目来源为 Codewars


Welcome.

In this kata you are required to, given a string, replace every letter with its position in the alphabet.

If anything in the text isn't a letter, ignore it and don't return it.

"a" = 1, "b" = 2, etc.

Example

alphabet_position("The sunset sets at twelve o' clock.")

Should return "20 8 5 19 21 14 19 5 20 19 5 20 19 1 20 20 23 5 12 22 5 15 3 12 15 3 11" (as a string)


题目要我们把一段字串依照 "a" = 1, "b" = 2 ... 的规则解析(没有分大写小),并且忽略掉非字母的字元,最後回传一段字串(如 example 那样)。

以下为我的解答:

def alphabet_position(text)
  text.downcase.bytes.map{ |char| char - 96 }.select{ |char| char >= 1 && char <= 26 }.join(' ')
end

首先,我们必须把整段字串转为小写,这里是使用 downcase 方法。

再来就是重头戏 bytes 方法,根据 Ruby官方文件所述,它会「returns an array of bytes in str」,那问题来了,什麽是 bytes?我们直接对题目的 example 用看看(别忘了先 downcase):

"The sunset sets at twelve o' clock.".downcase.bytes
  # => [116, 104, 101, 32, 115, 117, 110, 115, 101, 116, 32, 115, 101, 116, 115, 32, 97, 116, 32, 116, 119, 101, 108, 118, 101, 32, 111, 39, 32, 99, 108, 111, 99, 107, 46]

很神奇地,我们得到了一推数字,那这些数字是哪来的?还记得稍早所提的 ASCII 吗,让我们查查 ASCII 的编码表(维基百科),可以发现 a ~ z 字母的编码为 97 ~ 122,再去比对output 每个元素对应的原字元位置,不难发现它们的一致性,也就是 "a" = 97, "b" = 98 ... "z" = 122。

然後,只要再对阵列中的每个元素进行运算,减去 96 让 "a" = 1, "b" = 2 ... 就符合题目要的规则了。最後,只要筛掉(select 方法)其他字元的数字,再把阵列重新合成字串(join 方法),就大功告成了!

对比评分最高的解答:

def alphabet_position(text)
  text.gsub(/[^a-z]/i, '').chars.map{ |c| c.downcase.ord - 96 }.join(' ')
end

它是先用 gsub 将英文字母检索出来,再使用 chars 方法,依照官网所述,它会「returns an array of characters in str」,将字串打散成字母,并回传一个阵列。值得一提的是,这边的 ord 和 bytes 有点类似,但 ord 是回传 integer ordinal,英文的话是没什麽差,如果是其他语言的话结果会不相同。

今天的解题就到这啦,祝大家中秋节月圆人圆,明天上班活力满点~掰


<<:  Day21 Laravel - command & schedule

>>:  D07 / 怎麽显示大量资料 - Lazy composables ( LazyColumn & StickyHeader )

[Day28] 第二十八课 Azure灾害复原(DRaaS)-1[进阶]

先前提到Azure有很多客户拿来做第三份备份存放外,异地备援陆续也有不少客户来询问 了解,原因就在异...

浅谈MVVM

几个框架名称MVC/MVP/MVVM MVC: Model, View, Control MVP: ...

Day28 - 储存帐密及自动登入

今天来做储存帐密和自动登入的功能。 提醒:今天的内容缺少了加密储存密码,是极度危险的功能,这部份预计...

【Day14】verilog 中的可综合语句

我们都知道 verilog 是一种硬体描述语言,所以目的就是要能综合出实际的电路,但实际上在 ve...

Day 27 - Kotlin的类别继承和覆写

Day 27 - Kotlin的类别继承和覆写 昨天我们讲完了Kotlin客户端和和服务器端一起使用...