微信扫一扫打赏支持

dp3--codevs2598 编辑距离问题

dp3--codevs2598 编辑距离问题

一、心得

 1、字符串相关问题dp的时候从0开始是个陷阱

 

二、题目

2598 编辑距离问题

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
 
题目描述 Description

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

(1)删除一个字符;

(2)插入一个字符;

(3)将一个字符改为另一个字符。

将字符串A变换为字符串B所用的最少字符操作数称为字符串A到B的编辑距离,记为d(A,B)。试编写程序,对任给的2个字符串A和B,计算出它们的编辑距离d(A,B)。

输入描述 Input Description

输入文件edit.in有两行,第一行是字符串A,第二行是字符串B。

输出描述 Output Description

输出文件edit.out只有一行,即编辑距离d(A,B)。

样例输入 Sample Input

fxpimu

xwrs

样例输出 Sample Output

5

数据范围及提示 Data Size & Hint

40%的数据字符串A、B的长度均不超过100;

100%的数据字符串A、B的长度均不超过4000。

分类标签 Tags 点此展开 

 

 

三、分析

* codeVs2598编辑距离.cpp
* 分析:
* 状态:
* f[i][j]表示串s1的前i个字符和串s2的前j个字符的编辑距离
* 最终状态:
* f[len_s1][len_s2]
* 初始状态:
* f[i][0]=i;f[0][j]=j
* 状态转移方程:
* f[i][j]=f[i-1][j-1]; (s1[i]==s2[j])
* f[i][j]=min(f[i-1][j-1],f[i-1][j],f[i][j-1])+1; (s1[i]!=s2[j])

上图为初始化及分析过程

上图为dp数组结果

 

四、AC代码

94ms

  1 /*
  2  * codeVs2598编辑距离.cpp
  3  * 分析:
  4  * 状态:
  5  *         f[i][j]表示串s1的前i个字符和串s2的前j个字符的编辑距离
  6  * 最终状态:
  7  *         f[len_s1][len_s2]
  8  * 初始状态:
  9  *         f[i][0]=i;f[0][j]=j
 10  * 状态转移方程:
 11  *        f[i][j]=f[i-1][j-1]; (s1[i]==s2[j])
 12  *        f[i][j]=min(f[i-1][j-1],f[i-1][j],f[i][j-1])+1;  (s1[i]!=s2[j])
 13  *
 14  */
 15 
 16 #include <iostream>
 17 #include <string>
 18 #include <cstdio>
 19 using namespace std;
 20 string s1, s2;
 21 int f[4005][4005];
 22 int len_s1, len_s2;
 23 
 24 void readData() {
 25     cin >> s1 >> s2;
 26 }
 27 
 28 void printRead() {
 29     cout << s1 << endl << s2 << endl;
 30 }
 31 
 32 void initLen() {
 33     len_s1 = s1.length();
 34     len_s2 = s2.length();
 35 }
 36 
 37 void printLen() {
 38     cout << len_s1 << endl << len_s2 << endl;
 39 }
 40 
 41 void initArr_f() {
 42     //f数组最初的初始化
 43     for (int i = 0; i <= len_s1; i++) {
 44         for (int j = 0; j <= len_s2; j++) {
 45             f[i][j] = 0xfffff;
 46         }
 47     }
 48     //0列
 49     for (int i = 0; i <= len_s1; i++) {
 50         f[i][0] = i;
 51     }
 52     //0行
 53     for (int j = 0; j <= len_s2; j++) {
 54         f[0][j] = j;
 55     }
 56 }
 57 
 58 void printArr_f() {
 59     for (int i = 0; i <= len_s1; i++) {
 60         for (int j = 0; j <= len_s2; j++) {
 61             printf("%8d ", f[i][j]);
 62         }
 63         cout << endl;
 64     }
 65 }
 66 
 67 void init() {
 68     readData();
 69     //printRead();
 70     initLen();
 71     //printLen();
 72     initArr_f();
 73     //printArr_f();
 74 }
 75 
 76 int min3(int a,int b,int c){
 77     return min(min(a,b),c);
 78 }
 79 
 80 void dp() {
 81     for (int i = 1; i <= len_s1; i++) {
 82         for (int j = 1; j <= len_s2; j++) {
 83             if(s1[i-1]==s2[j-1]) f[i][j]=f[i-1][j-1];
 84             else{
 85                 f[i][j]=min3(f[i-1][j-1],f[i-1][j],f[i][j-1])+1;
 86             }
 87         }
 88     }
 89 }
 90 
 91 void printAns(){
 92     cout<<f[len_s1][len_s2]<<endl;
 93 }
 94 
 95 int main() {
 96     //freopen("src/codeVs2598in.txt", "r", stdin);
 97     init();
 98     dp();
 99     //printArr_f();
100     printAns();
101     return 0;
102 }
103 /*
104  * 注意点:
105  * 1、f数组最初的初始化不能忘记
106  *         f[i][j] = 0xfffff;
107  * 2、if(s1[i-1]==s2[j-1])这里忘记写减1了
108  *         字符串从0开始
109  */

 

 

 

五、注意点

1、f数组最初的初始化不能忘记
  f[i][j] = 0xfffff;

2、if(s1[i-1]==s2[j-1])这里忘记写减1了
  字符串从0开始

 

 

 

 

 

 

 

posted @ 2017-08-14 20:34  范仁义  阅读(353)  评论(0编辑  收藏  举报