Skip to content

Commit 8c702d1

Browse files
dp init #7
1 parent e90a6c7 commit 8c702d1

File tree

3 files changed

+203
-0
lines changed

3 files changed

+203
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/* Problem Statement : Minimum Number Of Insertions & Deletions needed in order to convert string a to string b.
2+
3+
Approach in short : The idea here is to identify the longest common subsequnce in a and b -> lcs.
4+
We can now utilize the lcs to obtain the differnces between the lengths of string a and that of string b , and the sum total of the differences is the resultant number of changes required in order to convert our string from a to b.
5+
6+
To compute the deletions needed : lengthOfstring(a) - lcs )-> res1
7+
To compute the insertions needed : lengthOfString(b) - lcs )-> res2
8+
Resultant difference = res1 + res2 -> The required answer.
9+
10+
Essentially, we are converting the string through the lcs. We count the number of operations(deletions) needed to get to lcs, and then we count the number of operations(insertions) need to get to string b from lcs, and add them both.
11+
12+
Sample Test Case :
13+
3
14+
heap pea
15+
geeksforgeeks forgeeks
16+
schoolstudents students
17+
case #1 : 3
18+
case #2 : 5
19+
case #3 : 6
20+
*/
21+
#include "headers.hpp"
22+
23+
int LCS(string &, string &, int, int);
24+
int minInsertionDeletionToConvertString(string a, string b, int n, int m)
25+
{
26+
int lcs = LCS(a, b, n, m);
27+
return (n - lcs) + (m - lcs); //(No of Deletions) + (No of Insertions)
28+
}
29+
int LCS(string &a, string &b, int n, int m)
30+
{
31+
int dp[n + 1][m + 1];
32+
// init for base case -> If either of the string is null, common subsequence length will be 0.
33+
for (int i = 0; i <= m; i++)
34+
dp[0][i] = 0;
35+
for (int i = 0; i <= n; i++)
36+
dp[i][0] = 0;
37+
38+
for (int i = 1; i <= n; i++)
39+
{
40+
for (int j = 1; j <= m; j++)
41+
{
42+
if (a[i - 1] == b[j - 1])
43+
dp[i][j] = 1 + dp[i - 1][j - 1];
44+
else
45+
{
46+
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
47+
}
48+
}
49+
}
50+
return dp[n][m];
51+
}
52+
int main()
53+
{
54+
vi output;
55+
tests(t)
56+
{
57+
string s1, s2;
58+
cin >> s1 >> s2;
59+
int n = s1.size(), m = s2.size();
60+
output.pb(minInsertionDeletionToConvertString(s1, s2, n, m));
61+
}
62+
63+
loop(i, output.size()) cout << "case #" << i + 1 << " : " << output[i] << endl;
64+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include "headers.hpp"
2+
3+
/*
4+
Sample Test Case :
5+
2
6+
abdegfr
7+
adgtfrw
8+
hgxsttu
9+
hegstu
10+
case #1 : adgfr
11+
case #2 : hgstu
12+
*/
13+
int **LCS(string s1, string s2, int n, int m)
14+
{
15+
int **dp = new int *[n + 1];
16+
loop(i, n + 1)
17+
dp[i] = new int[m + 1];
18+
// init for base case -> If either of the string is null, common subsequence length will be 0.
19+
for (int i = 0; i <= m; ++i)
20+
dp[0][i] = 0;
21+
for (int i = 0; i <= n; ++i)
22+
dp[i][0] = 0;
23+
24+
for (int i = 1; i <= n; i++)
25+
{
26+
for (int j = 1; j <= m; j++)
27+
{
28+
if (s1[i - 1] == s2[j - 1])
29+
dp[i][j] = (1 + dp[i - 1][j - 1]);
30+
else
31+
{
32+
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
33+
}
34+
}
35+
}
36+
return dp;
37+
}
38+
string lcsStrings(string s1, string s2, int n, int m)
39+
{
40+
string res = "";
41+
int **dp = LCS(s1, s2, n, m);
42+
int i = n, j = m;
43+
44+
while (i > 0 and j > 0)
45+
{
46+
if (s1[i - 1] == s2[j - 1])
47+
{
48+
res += s1[i - 1];
49+
i--;
50+
j--;
51+
}
52+
else
53+
{
54+
if (dp[i][j - 1] > dp[i - 1][j])
55+
j--;
56+
else
57+
i--;
58+
}
59+
}
60+
// resultant string has to be reversed in order to get the required LCS.
61+
int low = 0, high = res.size() - 1;
62+
while (low <= high)
63+
{
64+
swap(res[low], res[high]);
65+
low++;
66+
high--;
67+
}
68+
return res;
69+
}
70+
int main()
71+
{
72+
v(string) output;
73+
tests(t)
74+
{
75+
string s1, s2;
76+
cin >> s1 >> s2;
77+
int n = s1.size(), m = s2.size();
78+
79+
output.pb(lcsStrings(s1, s2, n, m));
80+
}
81+
82+
loop(i, output.size()) cout << "case #" << i + 1 << " : " << output[i] << endl;
83+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include "headers.hpp"
2+
/*
3+
Sample Test Case :
4+
3
5+
geek eke
6+
apple plex
7+
dogs fog
8+
case #1 : 5
9+
case #2 : 6
10+
case #3 : 5
11+
*/
12+
int LCS(string s1, string s2, int n, int m)
13+
{
14+
int dp[n + 1][m + 1];
15+
// init for base case -> If either of the string is null, common subsequence length will be 0.
16+
for (int i = 0; i <= m; i++)
17+
dp[0][i] = 0;
18+
for (int i = 0; i <= n; i++)
19+
dp[i][0] = 0;
20+
21+
for (int i = 1; i <= n; i++)
22+
{
23+
for (int j = 1; j <= m; j++)
24+
{
25+
if (s1[i - 1] == s2[j - 1])
26+
dp[i][j] = 1 + dp[i - 1][j - 1];
27+
else
28+
{
29+
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
30+
}
31+
}
32+
}
33+
return dp[n][m];
34+
}
35+
int shortestCommonSuperSequence(string s1, string s2, int n, int m)
36+
{
37+
/*Required soln will be, worst case of merging two strings (s1 + s2), where the length will be summ og the lengths of s1 and s2, i.e. (n+m).
38+
since, we know there had to be a common subsequence, the common subsequence must be counted twice in teh merged string of size (n+m). Thus, we essentially need to find the longest subsequence for s1 and s2, and subtraction of the LCS(s1,s2) from the merged string length (n+m) will give us the shortest possible common supersequence.
39+
*/
40+
int commonSubsequenceLength = LCS(s1, s2, n, m);
41+
return ((n + m) - commonSubsequenceLength);
42+
}
43+
44+
int main()
45+
{
46+
vi output;
47+
tests(t)
48+
{
49+
string s1, s2;
50+
cin >> s1 >> s2;
51+
int n = s1.size();
52+
int m = s2.size();
53+
output.pb(shortestCommonSuperSequence(s1, s2, n, m));
54+
}
55+
loop(i, output.size()) cout << "case #" << i + 1 << " : " << output[i] << endl;
56+
}

0 commit comments

Comments
 (0)