Scala小题目:001

练手题

题目

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和命令式思维的情况下它不见得会只是一个小问题……

分享到