// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.fixAddresses; import java.util.List; public final class StringUtils { private StringUtils() { // Hide default constructor for utilities classes } /** * Checks, if a string is either null or empty. * * @param txt * Text to check * @return True, if string is null or empty; otherwise false */ public static boolean isNullOrEmpty(String txt) { return txt == null || txt.length() == 0; } /** * Gets the length of the longest common substring of a and b * * @param a * First string * @param b * Second string * @return The length of the longest common substring or 0, if no common * sequence exists or one of the arguments are invalid. For * algorithm details please refer to {@link http * ://www.ics.uci.edu/~eppstein/161/960229.html} */ public static int lcsLength(String a, String b) { if (StringUtils.isNullOrEmpty(a)) return 0; if (StringUtils.isNullOrEmpty(b)) return 0; int[][] L = createLCSTable(a, b); return L[0][0]; } /** * Internal use only */ private static int[][] createLCSTable(String a, String b) { if (StringUtils.isNullOrEmpty(a)) return null; if (StringUtils.isNullOrEmpty(b)) return null; int m = a.length(); int n = b.length(); int[][] l = new int[m + 1][n + 1]; for (int i = 0; i < l.length; i++) { l[i] = new int[n + 1]; } int i, j; for (i = m - 1; i >= 0; i--) { for (j = n - 1; j >= 0; j--) { /* * if (i >= m || j >= n) { l[i][j] = 0; } else */ if (a.charAt(i) == b.charAt(j)) { l[i][j] = 1 + l[i + 1][j + 1]; } else { l[i][j] = Math.max(l[i + 1][j], l[i][j + 1]); } } } return l; } /** * Gets the longest common substring of a and b. * * @param a The first string. * @param b The second string. * @return the longest common substring of a and b */ public static String getLongestCommonSubstring(String a, String b) { if (StringUtils.isNullOrEmpty(a)) return null; if (StringUtils.isNullOrEmpty(b)) return null; StringBuffer sb = new StringBuffer(); int[][] l = createLCSTable(a, b); int m = a.length(); int n = b.length(); int i = 0; int j = 0; while (i < m && j < n) { char aa = a.charAt(i); char bb = b.charAt(j); if (aa == bb) { sb.append(aa); i++; j++; } else if (l[i + 1][j] >= l[i][j + 1]) { i++; } else { j++; } } return sb.toString(); } /** * @param needle The string to find the best match for. * @param haystack The list of strings to pick the best match from. * @return The string of the list with the longest common substring to needle or * <tt>null</tt>, if either <tt>needle</tt> or <tt>haystack</tt> is empty or null. */ public static String findBestMatch(String needle, List<String> haystack) { String bestMatch = null; double maxRatio = Double.MIN_VALUE; if (StringUtils.isNullOrEmpty(needle)) { return null; } if (haystack == null || haystack.size() == 0) { return null; } int lNeedle = needle.length(); for (String curString : haystack) { int ll = lcsLength(needle, curString); double ratio = ll / (double) lNeedle; if (ratio > maxRatio) { maxRatio = ratio; bestMatch = curString; } } return bestMatch; } }