你的身体由含有 DNA 的细胞组成。 这些细胞会定期损耗,需要更替,而它们靠分裂成子细胞来完成这件事。 事实上,普通人的身体一生中会经历大约 1 亿亿次细胞分裂!
细胞分裂时,它们的 DNA 也会复制。 有时在这个过程中会出差错,单个 DNA 片段会被编码成错误的信息。 如果我们比较两条 DNA 链并数出它们之间的差异,就能看出发生了多少错误。 这就是所谓的“汉明距离”。
汉明距离不只在生物学中有用,在许多科学领域都很有用,所以这是个值得熟悉的好说法 :)
计算两条 DNA 链之间的汉明距离。
我们使用字母 C、A、G 和 T 来表示 DNA。 两条链可能看起来像这样:
GAGCCTACTAACGGGAT
CATCGTAATGACGGCCT
^ ^ ^ ^ ^ ^^
它们有 7 处不同,因此汉明距离是 7。
汉明距离只对长度相同的序列有定义,所以在长度不同的序列之间计算它是行不通的。
Option 用来表示一个可能没有有用结果的计算
(例如因为错误或无效输入)。
如果你不熟悉Option,可以阅读这篇教程。
Option 是所谓的单子,它涵盖了一个“计算层面”的特性,在这里就是值可能不存在。
恰当使用单子可以写出非常简洁、优雅
且易读的代码。使用不当则很容易适得其反。
观看这个视频了解更多。
对于Option有几条经验法则:
def add1(x: Int): Option[Int] = Some(x + 1)
不如写成
def add1(x: Int): Int = x + 1
(有Option.map可以对这类简单函数做映射,
所以不必用Option把它们弄得累赘)。
2. 如果并不真的需要,就不要“解包”。
通常有内置函数能实现你的目的。过早解包的迹象
是isDefined/isEmpty或模式匹配。与其写成
val x: Option[Int] = ...
if (x.isDefined) x.get + 1 else 0
// or
x match {
case Some(n) => n + 1
case None => 0
}
不如写成
x map (_ + 1) getOrElse 0
Option实例时,建议这样做。与其写成val xo: Option[Int] = ...
val yo: Option[Int] = ...
val zo: Option[Int] = ...
xo.flatMap(x =>
yo.flatMap(y =>
zo.map(z =>
x + y + z)))
不如写成
for {
x <- xo
y <- yo
z <- zo
} yield x + y + z