using System;
using System.Collections.Generic;
namespace 編輯距離
{
class Program
{
public static readonly string str1 = "FAMILY";
public static readonly string str2 = "FRAME";
public static int[,] map = new int[str1.Length + 1, str2.Length + 1];
static void Main(string[] args)
{
EditDistence();
Console.WriteLine("行表示str1,列表示str2:");
DisplayMap();
Console.WriteLine();
DisplayRes();
Console.ReadKey();
}
/// <summary>
/// 編輯距離演算法
/// </summary>
static void EditDistence()
{
//初始化矩陣 第一行為0-str2的字串長度 第一列為0-str1的字串長度
for (int i = 0; i < str1.Length + 1; i++)
map[i, 0] = i;
for (int j = 0; j < str2.Length + 1; j++)
map[0, j] = j;
for (int i = 1; i < str1.Length + 1; i++)
{
for (int j = 1; j < str2.Length + 1; j++)
{
//若str1的第i個元素和str2的第j個元素相等 則map[i,j]等於 map中當前單元格左邊或者上面或左上較小的值
//若str1的第i個元素和str2的第j個元素不相等 則map[i,j]等於 map中當前單元格左邊或者上面或左上較小的值+1
if (str1[i - 1] == str2[j - 1])
map[i, j] = Math.Min(Math.Min(map[i - 1, j], map[i, j - 1]), map[i - 1, j - 1]);
else
map[i, j] = Math.Min(Math.Min(map[i - 1, j], map[i, j - 1]), map[i - 1, j - 1]) + 1;
}
}
}
/// <summary>
/// 顯示編輯距離演算法運算後的MAP矩陣
/// </summary>
static void DisplayMap()
{
Console.Write(" ");
for (int i = 0; i < str2.Length; i++)
{
Console.Write(" " + str2[i]);
}
Console.Write("\r\n");
for (int i = 0; i < str1.Length + 1; i++)
{
if (i > 0 && i < str1.Length + 1)
Console.Write(str1[i - 1] + " ");
else
Console.Write(" ");
for (int j = 0; j < str2.Length + 1; j++)
{
Console.Write(map[i, j] + " ");
}
Console.Write("\r\n");
}
}
/// <summary>
/// 顯示編輯距離長度和編輯過程
/// </summary>
static void DisplayRes()
{
Console.WriteLine("str1和str2的編輯距離是:" + map[str1.Length, str2.Length]);
Console.WriteLine("str1和str2的編輯距離的過程是:");
List<string> process = new List<string>(); //用於存放過程
int i = str1.Length, j = str2.Length;//分別表示MAP矩陣行和列
//逆序推測過程
while (i > 0 && j > 0)
{
//若str1的第i個元素和str2的第j個元素不相等 則map[i,j]的元素來源於 上面、左側、左上的元素+1,若想等則取後者 同時定位到取值元素所在的位置
//3鍾取值情況分別代表 刪除、插入、替換
//若str1的第i個元素和str2的第j個元素相等 則取左上角元素繼續執行迴圈
if (str1[i - 1] != str2[j - 1])
{
if (map[i, j] == (map[i - 1, j - 1] + 1))
{
process.Add(str1[i - 1] + " 替換為 " + str2[j - 1]);
i--;
j--;
continue;
}
if (map[i, j] == (map[i - 1, j] + 1))
{
process.Add("刪除 " + str1[i - 1]);
i--;
continue;
}
if (map[i, j] == (map[i, j - 1] + 1))
{
process.Add("插入 " + str2[j - 1]);
j--;
continue;
}
}
else
{
i--;
j--;
}
}
for (int index = process.Count - 1; index > -1; index--)
Console.WriteLine(process[index]);
}
}
}