使用动态规划求解字符串问题
2018-01-08 10:52
465 查看
72. Edit
Distance--字符串编辑问题
问题描述:
Given two words word1 and word2,find the minimum number of steps required to convert word1 to word2.
(each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
问题解析:
1. 本题是求两个字符串s1和s2,编辑s1让其变为s2。可以在s1中插入字符操作、删除字符操作、替换字符操作,每次操作增加步骤1次,求s1变为s2的最小步骤数。2. 解决此类问题经典解法就是用动态规划。
(1)s1大小为size1,s2大小为size2。定义一个size1+1*size2+1的dp,其中dp[i][j]表示s1的前i的字符变为和s2的前j个字符所需要的最小步骤数。
(2)dp[i][j]的值应该是:当s1[i]==s2[j]时,dp[i][j]==dp[i-1][j-1];当s[i] != s[j]时,dp[i][j] = dp[i-1][j]+1(删除一个字符)、dp[i][j] = dp[i][j-1] + 1(添加一个字符)、dp[i][j] = dp[i-1][j-1] + 1(替换一个字符)。选择三者步骤数最少的一个。
代码如下:
class Solution { public: // 使用动态规划来解决此问题,创建dp,dp[i][j]表示word1的i个字符转化为word2的前j个字符所需要的花费 int minDistance(string word1, string word2) { int m = (int)word1.size(); int n = (int)word2.size(); // 创建dp vector<vector<int>>dp(m+1, vector<int>(n+1, 0)); // 初始化第一行,代表word1为空时转化为word2 for(int j=1; j<=n; ++j) dp[0][j] = dp[0][j-1] + 1; // 初始化第一列,代表word2为空时转化为word1 for(int i=1; i<=m; ++i) dp[i][0] = dp[i-1][0] + 1; for(int i=1; i<=m; ++i) { for(int j=1; j<=n; ++j) { // dp[i-1][j]表示word1前i-1转换为word2前j个,需要花费,删掉1个就是前i和前j // dp[i][j-1]表示word1前i转换为word2前j-1个,需要花费,添加1个就是前i和前j // dp[i-1][j-1]表示word1前i-1转换为word2前j-1个需要花费。word1[i]==word2[j],则不需要花费就是前i和前j.否则需要替换多花费1 int z; dp[i][j] = dp[i-1][j] < dp[i][j-1] ? dp[i-1][j]+1 : dp[i][j-1]+1; z = (word1[i-1] == word2[j-1] ? dp[i-1][j-1] : dp[i-1][j-1]+1); dp[i][j] = dp[i][j] < z ? dp[i][j] : z; } } return dp[m] ; } };
115. Distinct
Subsequences---求字符串S中有几个字符串t
问题描述:
Given a string S and a string T, count the number of distinct subsequences of S whichequals T.
A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining
characters. (ie,
"ACE"is a subsequence of
"ABCDE"while
"AEC"is
not).
Here is an example:
S =
"rabbbit", T =
"rabbit"
Return
3.
问题解析:
1. 此题是求一个字符串S中有几个字符串t。可以转化为上题,只是通过在字符串S中删除字符来变为字符串t,看有几种解法。2. 解决此类问题经典解法就是用动态规划。
(1)s大小为size1,t大小为size2。定义一个size1*size2的dp,其中dp[i][j]表示s1的前i+1的字符变为和s2的前j+1个字符的方法数。
(2)dp[i][j]的值应该是:当s1[i]==s2[j]时,dp[i][j]==dp[i-1][j] + dp[i-1][j-1],表示的是使用当前这个字符和不要s中当前这个字符总共方法数;当s[i] != s[j]时,dp[i][j] = dp[i-1][j],s中当前这个字符一定用不上,所以表示不用当前这个字符的方法数。
代码如下:
class Solution { public: // 利用动态规划来做 int numDistinct(string s, string t) { if(s.empty()) return 0; if(t.empty()) return 1; int ssize = s.size(); int tsize = t.size(); vector<vector<int>> dp(ssize, vector<int>(tsize, 0)); // 填写第一行 if(s[0] ==t[0]) dp[0][0]=1; // 填写第一列 for(int i=1; i<ssize; ++i) { if(t[0] ==s[i]) dp[i][0] = 1+ dp[i-1][0]; else dp[i][0] = dp[i-1][0]; } // 填写剩余的dp for(int i=1; i<ssize; ++i) { for(int j=1; j<tsize; ++j) { if(s[i] == t[j]) dp[i][j] = dp[i-1][j-1] + dp[i-1][j]; else dp[i][j] = dp[i-1][j]; } } return dp[ssize-1][tsize-1]; } };
115. Distinct
Subsequences
相关文章推荐
- poj-1322-Chocolate 使用动态规划求解的一种概率问题的算法
- 使用动态规划求解旅行商问题
- VC中一个关于宏的使用问题,字符串之间转换,宽字符与普通字符
- VS2003升级到2005后使用AjaxControlToolkit的一诡异问题(已找到解决办法,求解原因)
- 动态规划法求解距离字符串问题
- 问题集锦07:使用T-SQL导入数据时报错“将截断字符串或二进制数据”
- 求解在SQL中使用了where列所遇到的问题
- 求解 关于 套汇问题 要求 使用 C++
- 动态规划求解最长公共子序列问题
- 动态规划求解编辑距离问题
- 使用不同的算法求解0-1背包问题
- 动态规划求解编辑距离问题(转)
- 使用栈和队列求解迷宫问题(标准库)
- 一个有趣的小测试——两个使用字符串描述的二进制数字相或的问题
- [原创]【动态规划求解“键盘上字母分配”问题】
- 动态规划求解最长公共子串问题
- 旧话重提---使用FxCop检测出字符串相关的2个问题
- 使用hibernate心得——字符串超长的解决办法(setCharacterStream出现顺序问题)
- 转:使用eval()解析JSON格式字符串应注意的问题
- Enterprise Library- Data Block使用oracle存储过程,字符串参数传入值为""时出现问题的解决