Skip to content

Instantly share code, notes, and snippets.

@gakuzzzz
Last active August 29, 2015 14:10
Show Gist options
  • Save gakuzzzz/ff01e878da8f98a3e645 to your computer and use it in GitHub Desktop.
Save gakuzzzz/ff01e878da8f98a3e645 to your computer and use it in GitHub Desktop.
文字列比較
@annotation.tailrec
def diff(s1: Seq[Char], s2: Seq[Char], acc: StringBuilder = new StringBuilder()): String = {
(s1, s2) match {
case (Nil , Nil) => acc.toString
case (x +: _ , Nil) => acc.append(s"[$x][$$END$$]").toString
case (Nil , y +: _) => acc.append(s"[$$END$$][$y]").toString
case (x +: xs, y +: ys) if x == y => diff(xs, ys, acc.append(x))
case (x +: _ , y +: _) => acc.append(s"[$x][$y]").toString
}
}
scala> diff("abc", "abcd")
res0: String = abc[$END$][d]
scala> diff("abcd", "abce")
res1: String = abc[d][e]
scala>
@reki2000
Copy link

reki2000 commented Dec 3, 2014

禁断のreturnで手続き型の例をつくってみました。

見た目は読みやすそうですがバグの温床感はありますね。

def diff(s1: String, s2: String) = {
    var i = 0
    var matched: String = ""
    for (c1: Char <- s1) {
      if (i >= s2.size) {
        return s"${matched}[$c1][$$END$$]")
      }
      val c2 = s2.charAt(i)
      if (c1 != c2) {
        return s"${matched}[$c1][$c2]")
      }
      matched += c1
      i += 1
    }
    if (i < s2.size) {
      return s"${s1}[$$END$$][${s2.charAt(i)}]"
    } else {
      return s1
    }
}

@gakuzzzz
Copy link
Author

gakuzzzz commented Dec 3, 2014

def diff(s1: String, s2: String): String = {
  val same = s1.zip(s2).takeWhile { case (x, y) => x == y }.unzip._1
  val (xs, ys) = (s1 drop same.size, s2 drop same.size)
  same.mkString("") ++
    (xs.headOption.fold("[$END$]")(c => s"[$c]")) ++
    (ys.headOption.fold("[$END$]")(c => s"[$c]"))
}

んー

@reki2000
Copy link

reki2000 commented Dec 3, 2014

再帰なしで頑張ってみました。

def diff(s1: String, s2: String) = {
  val (matched, unmatched) = s1 zip s2 partition {case(c1, c2) => (c1 == c2)}
  if (s1.size == s2.size && s1.size == matched.size) s1
  else s1.substring(0,matched.size) + (
     (s1.size - s2.size) match {
       case x if x > 0 =>  s"[${s1.last}][$$END$$]" 
       case x if x < 0 =>  s"[$$END$$][${s2.last}]" 
       case _ => s"[${unmatched(0)._1}][${unmatched(0)._2}]"
    })
}

@reki2000
Copy link

reki2000 commented Dec 3, 2014

バグ修正&ちょっとだけ整理……SMLかぶれ色出てるかも

def diff(s1: String, s2: String) = {
  val (matched, unmatched) = s1 zip s2 partition { case(c1, c2) => (c1 == c2) }
  matched.unzip._1.mkString + (
    (s1.size - s2.size) match {
      case x if x > 0 =>  s"[${matched.last._1}][$$END$$]"
      case x if x < 0 =>  s"[$$END$$][${matched.last._1}]"
      case _ if (s1.size == matched.size) => ""
      case _          => s"[${unmatched(0)._1}][${unmatched(0)._2}]"
    })
}```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment