练手题
题目
def strtr(src:String, from:String, to:String):String
from 和 to是等长的字符串, 要求将src中值为from(i)的字符转换成to(i)
例如: strtr(“abcdaf”, “ac”, “AC”) == “AbCdAf”
先来个Java风格版的代码:
def java1(src: String, from: String, to: String): String = {
val buffer = new StringBuffer()
val srcj = src.toVector
val fromj = from.toVector
val toj = to.toVector
var i = 0;
while (i < srcj.size) {
var c = srcj(i)
var j = 0
while (j < fromj.size) {
if (srcj(i) == fromj(j)) {
c = toj(j)
//break
}
j += 1
}
buffer append c
i += 1
}
buffer.toString
}
这段代码的主要意思就是:先把src, from, to三个字符串转换成三个序列,如:Vector。先迭代srcj,再将srcj(i)与from进行迭代比较。再将匹配的字符赋给buffer。
哎,这个风格的代码太繁琐了,我不想再仔细分析下去了,大伙就凑合着看看吧。
Scala风格版(1)
def scala1(src: String, from: String, to: String): String = {
val mat = from zip to
src.map(s => mat.find(_._1 == s).map(_._2).getOrElse(s))
}
这代码TM的一看就清爽多了,不解释!
Scala风格版(2)
def scala2(src: String, from: String, to: String): String = {
val mat = (from zip to).toMap
src.map(s => mat.getOrElse(s, s))
}
嗯,这版更清爽。来,说说呗!(from zip to)
这句代码的意思是把from和zip两字符串合并成一个一一对应的IndexSeq,比如:from = “abc”, to = “XYZ”,那mat = IndexSeq((‘a’, ‘X’), (‘b’, ‘Y’), (‘c’, ‘Z’))。这后那个toMap就一目了然了。s => mat.getOrElse(s, s)
这函数的意思是有一个参数s,类型是Char,在mat中查找key为s的value,若key不存在则返回默认值s(就是getOrElse方法的第二个参数)。src.map(fcuntion)方法的意思就是对src这个字符串进行迭代,并对每次迭代的元素应用function这个函数进行计算并回返计算后的值。
总结
好了,一个简单的小问题。发现在使用了scala及函数式编程思维后它的确是一个小问题。但可惜的是在使用java和命令式思维的情况下它不见得会只是一个小问题……