标签:proc asc int 字符串 ios out color cstring 个人
题意:两个字符串str1,str2。让str1去匹配str2。可以对str1增,删,改。
Insert pos,value
Delete pos
Replace pos,value
输入样例:
abcac
bcd
aaa
aabaaaa
输出样例:
3 1 Delete 1 2 Replace 3,d 3 Delete 4 4 1 Insert 1,a 2 Insert 2,a 3 Insert 3,b 4 Insert 7,a
方法:动态规划
1.dp[i][j],i是str1的第i位,j是str2的,表示到str1[i-1],str[j-1]匹配后需要多少步
2.dp[x][y]=min(dp[x-1][y]+1,dp[x][y-1]+1,dp[x-1][y-1]+(str1[i-1] 与 str2[j-1] 是否一样,一样就不需要操作(改),不一样就需要改 ) );
3.边界条件:str1长度为0时,dp[0][str2.size()] 需要str2.size() 步(增str2.size()次);
4.遍历顺序:asc(顺序)
注意:
1.dp[str1.size()][str2.size()];//错误演示:dp[len1][len2];
2.增删改;改优于增,改优于删。
不太友好的代码如下:
#include <iostream> #include <cstring> #include <string> #include <cstdio> using namespace std; #define xx 81 int min(int x, int y, int z) { x = x < y ? x : y; return x < z ? x : z; } int main() { string str1, str2; int dp[xx][xx]; bool flag[xx][xx]; int len1, len2; while (cin >> str1 >> str2) { len1 = str1.size(), len2 = str2.size(); //cout << len1 << " " << len2 << endl; //执行flag for (int i = 0; i < len1; i++) for (int j = 0; j < len2; j++) flag[i][j] = str1[i] == str2[j] ? 0 : 1; //确定边界 for (int i = 0; i < xx; ++i)dp[i][0] = dp[0][i] = i; //执行dp for (int i = 1; i <= len1; i++) { for (int j = 1; j <= len2; j++) { dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1, dp[i - 1][j - 1] + flag[i-1][j-1]);//增 删 改 } } //操作 cout << dp[len1][len2] << "\n"; for (int k = 1; k <= dp[str1.size()][str2.size()];) { int t; if (len1 == 0 && len2 != 0)t = 1; else if (len1 != 0 && len2 == 0)t = 2; else if (len1 != 0 && len2 != 0) { /* if (dp[len1][len2 - 1] == min(dp[len1 - 1][len2], dp[len1][len2 - 1], dp[len1 - 1][len2 - 1]))t = 1;//增 else if (dp[len1 - 1][len2] == min(dp[len1 - 1][len2], dp[len1][len2 - 1], dp[len1 - 1][len2 - 1]))t = 2;//删 else if (dp[len1 - 1][len2 - 1] == min(dp[len1 - 1][len2], dp[len1][len2 - 1], dp[len1 - 1][len2 - 1]))t = (dp[len1 - 1][len2 - 1] == dp[len1][len2] ? 0 : 3);//是否改 */ //改优先与增,改优先于删 if (dp[len1 - 1][len2 - 1] == min(dp[len1 - 1][len2], dp[len1][len2 - 1], dp[len1 - 1][len2 - 1]))t = (dp[len1 - 1][len2 - 1] == dp[len1][len2] ? 0 : 3);//是否改 else if (dp[len1][len2 - 1] == min(dp[len1 - 1][len2], dp[len1][len2 - 1], dp[len1 - 1][len2 - 1]))t = 1;//增 else if (dp[len1 - 1][len2] == min(dp[len1 - 1][len2], dp[len1][len2 - 1], dp[len1 - 1][len2 - 1]))t = 2;//删 } //cout << k << " " << dp[str1.size()][str2.size()] << endl; //cout << len1 << len2 << endl; switch (t) { case 0:len1--, len2--;break;//不改 case 1:printf("%d Insert %d,%c\n", k++, len1 + 1, str2[--len2]);break;//增 case 2:printf("%d Delete %d\n", k++, len1--);break;//删 case 3:printf("%d Replace %d,%c\n", k++, len1--, str2[--len2]);break;//改 default:break; } } //cout << " over " << endl; } return 0; }
个人建议只看看我的做题思路就好,代码就自己写吧~我自己都看着头大。
String Distance and Transform Process 小白详解
标签:proc asc int 字符串 ios out color cstring 个人
原文地址:https://www.cnblogs.com/sos3210/p/13384731.html