先說點題外話,早上同窗給我了一套卷子,讓我作,他對象的機試題,第一題是求點隊中的最小距離點對,沒說數據量,那確定直接暴力就好了(有給分點,正確輸入給5分,什麼什麼給五分),或者分治算法(編程之美里的);第二題是替換字符串;第三題是求給出的四邊形的面積,逼着認爲這個不能用海倫公式,由於多是凹四邊形,須要向量公式。題目如此簡單,這就是北郵,這種題目能考察出來水平麼,哎,或許真是考研的學生水平都不高,只是會看書會考試而已。算法
昨晚吃飯,本科的張同窗驚訝於我說的體重,找了個診所,直接進去測,發現真的是70kg,本科時候我歷來不到60kg。編程
1、問題來源函數
看雲計算的書,提到微博去重,由於數據量巨大,須要先Hash再MapReduce,那麼如何Hash把類似的微博儘量放到同一個桶裏呢?用哪一個Hash呢,做者提出了局部敏感Hash算法,中間的距離度量函數可使用編輯距離(Edit Distance),可是編輯距離右腳Levenshtein萊溫斯坦距離,即LD,寫到這,筆者忽然想到,ED距離是否是就是編輯距離,原來我認爲是歐幾里得距離。哈哈,這真是「文章本天成,妙手偶得之」。ui
我查了資料發現編輯距離在NLP(神經語言程序學)中應用普遍。雲計算
2、問題分析spa
下面資料,來自北大,這真是人才的搖籃,我不知道我咋找到這個資料的,記得之前這類資料也都是pdf連接,如今依舊。並且筆者發現,他們的資料更加細緻,可能出現的問題都作了標註,這些問題包括讀者能想到的和不能想到的,頗有啓發性和警醒做用,爲什麼說警醒,由於你忽然發現本身的誤解,那麼就不會那麼自滿了;北大和我校的區別,就像高中老師和大學老師的區別。此偶之愚見也。對象
1.引入blog
源文:She is a star with the theatre company.遞歸
機器譯文:她 是 與 劇院 公司 的 一 顆 星。字符串
參考譯文:她 是 劇團 的 明星。
2.算法分析
看完接下來的資料,我發現,Dijkstra算法從後往前推結果,編程倒是從前日後,可是不理解,如今想來,這是必然的。由於d[i][j]=min{d[i-1][j-1]……},結果是d[m][n]不算出前面的怎麼計算出d[m][n],從前日後是遞推,從後往前相似遞歸,哈哈。
參考資料:http://ccl.pku.edu.cn/doubtfire/Course/Computational%20Linguistics/contents/Minimum%20Edit%20Distance.pdf
3、算法實現
1.Java版本
上面算法的變形實現,或者直接寫個min(a,b,c)函數就是上面的算法實現了。
public class MinimumEditDistance { public static int minEditDistance(String dest, String src) { int[][] f = new int[dest.length()+1][src.length() + 1]; f[0][0] = 0; for (int i = 1; i < dest.length() + 1; i ) { f[i][0] = i; } for (int i = 1; i < src.length() + 1; i ) { f[0][i] = i; } for (int i = 1; i < dest.length() + 1; i ) { for (int j = 1; j < src.length() + 1; j ) { // 替換的開銷 int cost = 0; if (dest.charAt(i - 1) != src.charAt(j - 1)) { cost = 1; } int minCost; if (f[i - 1][j] < f[i][j - 1]) { minCost = f[i - 1][j] + 1; } else { minCost = f[i][j - 1] + 1; } if (minCost > f[i - 1][j - 1] + cost) { minCost = f[i - 1][j - 1] + cost; } f[i][j] = minCost; } } return f[dest.length()][src.length()]; } public static void main(String[] args) { System.out.println(minEditDistance("kindle", "ainelw")); } }
2.C/C++版本
#include #include char s1[1000],s2[1000]; int min(int a,int b,int c) { int t = a < b ? a : b; return t < c ? t : c; } void editDistance(int len1,int len2) { int** d=new int*[len1+1]; for(int k=0;k<=len1;k++) d[k]=new int[len2+1]; int i,j; for(i = 0;i <= len1;i++) d[i][0] = i; for(j = 0;j <= len2;j++) d[0][j] = j; for(i = 1;i <= len1;i++) for(j = 1;j <= len2;j++) { int cost = s1[i] == s2[j] ? 0 : 1; int deletion = d[i-1][j] + 1; int insertion = d[i][j-1] + 1; int substitution = d[i-1][j-1] + cost; d[i][j] = min(deletion,insertion,substitution); } printf("%d\n",d[len1][len2]); for(int k=0;i<=len1;k++) delete[] d[k]; delete[] d; } int main() { while(scanf("%s %s",s1,s2) != EOF) editDistance(strlen(s1),strlen(s2)); }