Find closest match for misspelled city names?

前端 未结 3 696
醉酒成梦
醉酒成梦 2020-12-21 00:15

I have a list of cities that have numerous incorrect spelling for the same city. One city is misspelled 18 times! I am trying to clean this up but its taking hours. Is th

3条回答
  •  粉色の甜心
    2020-12-21 00:38

    you could use a damerau-levenstein function to get the string distance between two strings. (This also checks for transposition)

    http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance

    If your tables are big then you might need to optimise the algo a bit to break once the string distance exceeds a threashold.

    Also if you can assume that the first letter of the city is typed correctly that should reduce the number of comparisons to.

    Its not PHP, but if its of any help heres a java version I wrote:

    class LevinshteinDistance{
        public static void main(String args[]){
            if(args.length != 2){
                System.out.println("Displays the Levenshtein distance between 2 strings");
                System.out.println("Usage: LevenshteinDistance stringA stringB");
            }else{
                int distance = getLevenshteinDistance(args[0], args[1]);
                System.out.print(getLevenshteinMatrix(args[0], args[1]));
                System.out.println("Distance: "+distance);
            }
        }   
    
        /**
         * @param a first string for comparison
         * @param b second string for comparison
         * @param caseSensitive whether or not to use case sensitive matching
         * @return a levenshtein string distance
         */  
        public static int getLevenshteinDistance(String a, String b, boolean caseSensitive){
            if(! caseSensitive){
            a = a.toUpperCase();
            b = b.toUpperCase();
            }
            int[][] matrix = generateLevenshteinMatrix(a, b);
            return matrix[a.length()][b.length()];
        }
    
        /**
         * @param a first string for comparison
         * @param b second string for comparison
         * @return a case sensitive levenshtein string distance
         */  
        public static int getLevenshteinDistance(String a, String b){
            int[][] matrix = generateLevenshteinMatrix(a, b);
            return matrix[a.length()][b.length()];
        }
    
        /**
         * @param a first string for comparison
         * @param b second string for comparison
         * @return a  case sensitive string representation of the search matrix
         */  
        public static String getLevenshteinMatrix(String a, String b){
            int[][] matrix = generateLevenshteinMatrix(a, b);
            StringBuilder result = new StringBuilder();
            final int ROWS = a.length()+1;
            final int COLS = b.length()+1;
    
            result.append(rowSeperator(COLS-1, false));
            result.append("|    "+b+" |\n");
            result.append(rowSeperator(COLS-1, true));  
    
            for(int r=0; r 0){
                    result.append(a.charAt(r-1));
                }else{
                    result.append(' ');
                }
                result.append(" |");
                for(int c=0; c 1 && c > 1) && a.charAt(r-2) == cB && cA == b.charAt(c-2) ){
                        int transposition = matrix[r-2][c-2]+cost;
                        minimum = Math.min(minimum, transposition);
                    }
                    matrix[r][c] = minimum;
                }
            }   
            return matrix;
        }
    }
    

提交回复
热议问题