Created
September 22, 2015 15:33
-
-
Save aspiwack/ed53675d5a58ac1bf115 to your computer and use it in GitHub Desktop.
Simple, naïve, generic diff implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package util | |
import scala.reflect.ClassTag | |
sealed abstract class Diffed[+A] | |
final case class Unchanged[+A](x: A) extends Diffed[A] { | |
override def toString: String = "Unchanged(" + x + ")" | |
} | |
final case class Changed[+A](x: A) extends Diffed[A] { | |
override def toString: String = "Changed(" + x + ")" | |
} | |
object StringDiff extends App { | |
def maxVector[A](v1: Vector[A], v2: Vector[A]): Vector[A] = | |
if (v1.length > v2.length) v1 | |
else v2 | |
// returns the longest common subsequence between [l1] and [l2] | |
def longestSubsequence[A: ClassTag](l1: Array[A], l2: Array[A]): Array[A] = { | |
// initialize matrix for dynamic algorithm | |
val n1 = l1.length | |
val n2 = l2.length | |
val lsubs: Array[Array[Vector[A]]] = Array.ofDim[Vector[A]](n1 + 1, n2 + 1) | |
// initialize matrix border | |
lsubs(0)(0) = Vector() | |
for (i <- 0 until n1) lsubs(i + 1)(0) = Vector() | |
for (j <- 0 until n2) lsubs(0)(j + 1) = Vector() | |
// fill matrix | |
for ( | |
i <- 0 until n1; | |
j <- 0 until n2 | |
) { | |
if (l1(i) == l2(j)) { | |
lsubs(i + 1)(j + 1) = lsubs(i)(j) :+ l1(i) | |
} else { | |
lsubs(i + 1)(j + 1) = maxVector(lsubs(i)(j + 1), lsubs(i + 1)(j)) | |
} | |
} | |
// build return value | |
lsubs(n1)(n2) toArray | |
} | |
// [common] is a subsequence of [l], assumed to be the longest common | |
// subsequence with some other array | |
def diffOf[A: ClassTag](common: Array[A], l: Array[A]): Array[Diffed[A]] = { | |
var cursor = 0 | |
l map ((x: A) => if (cursor < common.length && x == common(cursor)) { cursor += 1; Unchanged(x) } else Changed(x)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment