■要求定義
– ファイルとファイルの内容の違いを表示する
– diff 旧ファイル名 新ファイル名
■diffのサンプル
e.g.
before.txt
体重 66Kg abcdef 123456
after.txt
体重 64Kg abcdef 123456
$ diff before.txt after.txt
1c1
< 体重 66Kg
---
> 体重 64Kg
■検討
– 差分の計算には(1)編集距離、(2)Longest Common Subsequence:最長共通部分列、(3)Shortest Edit Script
– Wuアルゴリズムでは、2つの要素列を、エディットグラフに見立てて、点(0,0)から点(M,N)までの最短経路を求める問題に還元する
– Wuアルゴリズムは難易度が高いか?
同じか否かを検出
int main(){
int i, n, c1, c2;
FILE *fp1, *fp2;
fp1 = fopen("before.txt", "r");
fp2 = fopen("after.txt", "r");
if(fp1==NULL || fp2==NULL){
printf("file open error\n");
return 1;
}
int ln = 1;
int cl = 0;
while ((c1=fgetc(fp1))!=EOF && (c2=fgetc(fp2))!=EOF){
ln += (c1 == '\n') ? 1: 0;
cl += (c1 == '\n') ? 0: ++cl;
if(c1 != c2){
printf("difference found [%c][%c] at line %d col %d\n", c1, c2, ln, cl);
fclose(fp1);
fclose(fp2);
return 2;
}
}
printf("no difference\n");
fclose(fp1);
fclose(fp2);
return 0;
}
$ ./dev
difference found [6][4] at line 1 col 1022
$ ./dev
no difference
天才がいるな。
■動的計画法(JavaScript)
function distance(A, B){
const M = A.length;
const N = B.length;
// DPのテーブル(大きさ(M + 1)*(N + 1)の2次元配列)
// D[i][j] = (0, 0)から(i, j)までの最小コスト(編集距離)
const D = new Array(M + 1);
for(let i = 0; i <= M; i++){
D[i] = new Array(N + 1);
// (0,0)から(i,0)までの距離はi
D[i][0] = i;
}
for(let j = 1; j <= N; j++){
// (0,0)から(0, j)までの距離はj
D[0][j] = j;
}
// D[i][j]を順番に求める
for(let i = 1; i <= M; i++){
for(let j = 1; j <= N; j++){
// 縦横については +1, 斜めの辺については + 0
D[i][j] = A[i-1] === B[j - 1]
? Math.min(D[i-1][j] +1, D[i][j-1]+1, D[i-1][j-1])
: Math.min(D[i-1][j] +1, D[i][j-1]+1);
}
}
return D[M][N];
}
gonpなどwuアルゴリズムにはライブラリがあるようです。