Last active
February 15, 2017 07:02
-
-
Save Mindstormer619/55fb4883ac454d154c08252125422c56 to your computer and use it in GitHub Desktop.
Java implementation of Levenshtein distance. Follows a lot of "clean code" principles I learnt from Robert C Martin's book Chapters 1-4.
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
import java.util.ArrayList; | |
import java.util.Scanner; | |
public class EditDistance { | |
private static final int INSERT_COST = 1; | |
private static final int DELETE_COST = 1; | |
private static final int SUBST_COST = 2; | |
private static int[][] distances; | |
private static String fromString; | |
private static String toString; | |
public static int getDistance(String fromString, String toString) { | |
EditDistance.fromString = fromString; | |
EditDistance.toString = toString; | |
int fromLength = fromString.length(); | |
int toLength = toString.length(); | |
initializeDistances(fromLength, toLength); | |
for (int i = 1; i <= fromLength; i++) { | |
for (int j = 1; j <= toLength; j++) { | |
calculateDistance(i, j); | |
} | |
} | |
return distances[fromLength][toLength]; | |
} | |
private static void initializeDistances(int fromLength, int toLength) { | |
distances = new int[fromLength+1][toLength+1]; // index range [0-fromLength][0-toLength] | |
for (int i = 0; i <= fromLength; i++) { | |
distances[i][0] = i; | |
} | |
for (int j = 0; j <= toLength; j++) { | |
distances[0][j] = j; | |
} | |
} | |
private static void calculateDistance(int from, int to) { | |
int delCost = getDeleteCost(fromString.charAt(from-1)) + distances[from-1][to]; // deleting the last character | |
int insCost = getInsertCost(toString.charAt(to-1)) + distances[from][to-1]; // adding a character at the end | |
int subCost = getSubstCost(fromString.charAt(from-1), toString.charAt(to-1)) + distances[from-1][to-1]; // replacing the last character | |
distances[from][to] = getMinimum(delCost, insCost, subCost); | |
} | |
private static int getDeleteCost(char charToDelete) { | |
return DELETE_COST; | |
} | |
private static int getInsertCost(char charToInsert) { | |
return INSERT_COST; | |
} | |
private static int getSubstCost(char fromChar, char toChar) { | |
if (fromChar == toChar) return 0; | |
else return SUBST_COST; | |
} | |
private static int getMinimum(int a, int b, int c) { | |
if (a < b) { | |
if (a < c) return a; | |
else return c; | |
} | |
else { | |
if (b < c) return b; | |
else return c; | |
} | |
} | |
public static void main(String[] args) { | |
char again = 'n'; | |
Scanner sc = new Scanner(System.in); | |
String fromString; | |
String toString; | |
do { | |
System.out.print("Enter source string:"); | |
fromString = sc.nextLine(); | |
System.out.print("Enter destination string:"); | |
toString = sc.nextLine(); | |
System.out.println("Computing for " + fromString + " and " + toString + ":"); | |
System.out.println(EditDistance.getDistance(fromString, toString)); | |
System.out.print("\nGo again? (y/n)"); | |
again = sc.next().charAt(0); | |
sc.nextLine(); // clearing scanner buffer | |
} | |
while (again == 'y'); | |
sc.close(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment