编辑距离问题(1)

问题描述:

设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括:

删除一个字符;
(2)插入一个字符;
(3)将一个字符改为另一个字符。
将字符串A变换为字符串B所用的最少字符操作数称为字符串A到B的编辑距离,记为d(A,B)。试设计一个有效算法,对任给的2个字符串A和B,计算出它们的编辑距离d(A,B)。

 

问题分析:

 

将字符串拆分为字符数组比较

1.当A.length=0,则d(A,B)=B.length

2.当B.length=0,则d(A,B)=A.length

3.为d(A,B)赋初值:

A.length=m,B.length=0,d(0,0)~d(m-1,0)=0,1...,m-1;

A.length=0,B.length=n,d(0,0)~d(0,n-1)=0,1...,n-1;

4.A->BA中删除一个元素 d[i - 1][j] + 1‚A中插入一个元素d[i][j-1]+1ƒ将A中的一个元素改变为B中的元素d[i-1][j-1]+1

所以d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1]

+ A[i]==B[i]?0:1);

例如:str1={f, x, p, i, m, u},str2={x,w,r,s}

初始化d[A][B]={{0, 1, 2, 3}, {1, 0, 0, 0}, {2, 0, 0, 0}, {3, 0, 0, 0}, {4, 0, 0, 0}, {5, 0, 0, 0}}

当i=1,j=1时d[1][1]=min(d[0][1]+1,d[1][0]+1,d[0][0]+1)=1

当i=1,j=2时d[1][2]=min(d[0][2]+1,d[1][1]+1,d[0][1]+1)=2

当i=1,j=3时d[1][3]=min(d[0][3]+1,d[1][2]+1,d[0][2]+1)=3

当i=2,j=1时d[2][1]=min(d[1][1]+1,d[2][0]+1,d[1][0]+1)=2

当i=2,j=2时d[2][2]=min(d[1][2]+1,d[2][1]+1,d[1][1]+1)=2

当i=2,j=3时d[2][3]=min(d[1][3]+1,d[2][2]+1,d[1][2]+1)=3

当i=3,j=1时d[3][1]=min(d[2][1]+1,d[3][0]+1,d[2][0]+1)=3

当i=3,j=2时d[3][2]=min(d[2][2]+1,d[3][1]+1,d[2][2]+1)=3

当i=3,j=3时d[3][3]=min(d[2][3]+1,d[3][2]+1,d[2][3]+1)=3

当i=4,j=1时d[4][1]=min(d[3][1]+1,d[4][0]+1,d[3][0]+1)=4

当i=4,j=2时d[4][2]=min(d[3][2]+1,d[4][1]+1,d[3][1]+1)=4

当i=4,j=3时d[4][3]=min(d[3][3]+1,d[4][2]+1,d[3][2]+1)=4

当i=5,j=1时d[5][1]=min(d[4][1]+1,d[5][0]+1,d[4][0]+1)=5

当i=5,j=2时d[5][2]=min(d[4][2]+1,d[5][1]+1,d[4][1]+1)=5

当i=5,j=3时d[5][3]=min(d[4][3]+1,d[5][2]+1,d[4][2]+1)=5

d[6][4]=[[0, 1, 2, 3], [1, 1, 2, 3], [2, 2, 2, 3], [3, 3, 3, 3], [4, 4, 4, 4], [5, 5, 5, 5]]

 

 

参考代码如下:

 

package homework;

import java.util.Scanner;

public class test {

	private static int edit(char[] st1, char[] st2) {
		int m = st1.length;
		int n = st2.length;
		int d[][] = new int[m][n];
		if (m == 0) {
			return n;
		}
		if (n == 0) {
			return m;
		}
		// 当d[A][B]A个数为从0到m,B个数为0,则d[A][B]=0,1 2 3 m
		for (int i = 0; i < m; i++) {
			d[i][0] = i;
		}
		// 当d[A][B]B个数为从0到m,A个数为0,则d[A][B]=0,1 2 3....m
		for (int j = 0; j < n; d[0][j] = j++) {
			d[0][j] = j;
		}
		for (int i = 1; i < m; i++) {
			for (int j = 1; j < n; j++) {
				int cost = st1[i] == st2[j] ? 0 : 1;
				d[i][j] = Min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1]
						+ cost);
			}
		}
		return d[m - 1][n - 1];
	}

	static int Min(int a, int b, int c) {
		int min = a;
		if (b < min)
			min = b;
		if (c < min)
			min = c;
		return min;
	}

	public static void main(String[] args) {
		System.out.println("请输入两个字符串:");
		String str1 = new String();
		String str2 = new String();
		Scanner input = new Scanner(System.in);
		str1 = input.nextLine();
		char st1[] = str1.toCharArray();
		str2 = input.nextLine();
		char st2[] = str2.toCharArray();
		System.out.println(edit(st1, st2));
	}

}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值