php – 查找拼写错误的城市名称最匹配的匹配项?
作者:互联网
我有一个城市列表,这些城市的拼写错误很多.一个城市拼错了18次!我正在努力清理它,但需要花费数小时.是否有一些算法可以“猜测”这些拼写错误的有效城市名称?某种形式的加权?数据在MySQL中,我有一个正确拼写的表格,以便进行比较.
有什么想法吗?如果可能,PHP示例将有所帮助.
解决方法:
你可以使用damerau-levenstein函数来获得两个字符串之间的字符串距离. (这也检查换位)
http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
如果您的表很大,那么一旦字符串距离超过threashold,您可能需要稍微优化算法.
此外,如果你可以假设城市的第一个字母输入正确,应该减少比较的数量.
它不是PHP,但如果它的任何帮助下面是我写的java版本:
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<ROWS; r++){
result.append('|');
if(r > 0){
result.append(a.charAt(r-1));
}else{
result.append(' ');
}
result.append(" |");
for(int c=0; c<COLS; c++){
result.append(matrix[r][c]);
}
result.append(" |\n");
}
result.append(rowSeperator(COLS-1, false));
return result.toString();
}
private static String rowSeperator(final int LEN, boolean hasGap){
StringBuilder result = new StringBuilder();
if(hasGap){
result.append("+ +-");
}else{
result.append("+----");
}
for(int i=0; i<LEN; i++)
result.append('-');
result.append("-+\n");
return result.toString();
}
private static int[][] generateLevenshteinMatrix(String a, String b){
final int ROWS = a.length()+1;
final int COLS = b.length()+1;
int matrix[][] = new int[ROWS][COLS];
for(int r=0; r<ROWS; r++){
matrix[r][0]=r;
}
for(int c=0; c<COLS; c++){
matrix[0][c]=c;
}
for(int r=1; r<ROWS; r++){
char cA = a.charAt(r-1);
for(int c=1; c<COLS; c++){
char cB = b.charAt(c-1);
int cost = (cA == cB)?0:1;
int deletion = matrix[r-1][c]+1;
int insertion = matrix[r][c-1]+1;
int substitution = matrix[r-1][c-1]+cost;
int minimum = Math.min(Math.min(deletion, insertion), substitution);
if( (r > 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;
}
}
标签:php,algorithm,mysql,misspelling 来源: https://codeday.me/bug/20190626/1299083.html