Skip to content

Commit 3280d46

Browse files
committed
fix: cleanup longest_common_string.cpp
1 parent 0217450 commit 3280d46

File tree

1 file changed

+101
-44
lines changed

1 file changed

+101
-44
lines changed
Lines changed: 101 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,110 @@
1-
#include <iosrteam>
2-
using namespace std;
1+
/**
2+
* @file
3+
* @brief contains the definition of the function longest_common_string_length
4+
* @details
5+
* the function longest_common_string_length computes the length
6+
* of the longest common string which can be created of two input strings
7+
* by removing characters from them
8+
*/
39

4-
int max(int a, int b) { return (a > b) ? a : b; }
10+
#include <cassert> /// for assert
11+
#include <string> /// for std::string
12+
#include <vector> /// for std::vector
513

6-
int main() {
7-
char str1[] = "DEFBCD";
8-
char str2[] = "ABDEFJ";
9-
int i, j, k;
10-
int n = strlen(str1) + 1;
11-
int m = strlen(str2) + 1;
12-
// cout<<n<<" "<<m<<"\n";
13-
int a[m][n];
14-
15-
for (i = 0; i < m; i++) {
16-
for (j = 0; j < n; j++) {
17-
if (i == 0 || j == 0)
18-
a[i][j] = 0;
19-
20-
else if (str1[i - 1] == str2[j - 1])
21-
a[i][j] = a[i - 1][j - 1] + 1;
22-
23-
else
24-
a[i][j] = 0;
25-
}
26-
}
14+
/**
15+
* @brief computes the length of the longest common string created from input
16+
* strings
17+
* @details has O(str_a.size()*str_b.size()) time and memory complexity
18+
* @param str_a first input string
19+
* @param str_b second input string
20+
* @returns the length of the longest common string which can be strated from
21+
* str_a and str_b
22+
*/
23+
std::size_t longest_common_string_length(const std::string& str_a,
24+
const std::string& str_b) {
25+
const auto size_a = str_a.size();
26+
const auto size_b = str_b.size();
27+
std::vector<std::vector<std::size_t>> sub_sols(
28+
size_a + 1, std::vector<std::size_t>(size_b + 1, 0));
2729

28-
/*for(i=0;i<m;i++)
29-
{
30-
for(j=0;j<n;j++)
31-
cout<<a[i][j]<<" ";
32-
cout<<"\n";
33-
}*/
34-
35-
int ma = -1;
36-
int indi, indj;
37-
for (i = 0; i < m; i++) {
38-
for (j = 0; j < n; j++) {
39-
if (a[i][j] > ma) {
40-
ma = a[i][j];
41-
indi = i;
42-
indj = j;
30+
const auto limit = static_cast<std::size_t>(-1);
31+
for (std::size_t pos_a = size_a - 1; pos_a != limit; --pos_a) {
32+
for (std::size_t pos_b = size_b - 1; pos_b != limit; --pos_b) {
33+
if (str_a[pos_a] == str_b[pos_b]) {
34+
sub_sols[pos_a][pos_b] = 1 + sub_sols[pos_a + 1][pos_b + 1];
35+
} else {
36+
sub_sols[pos_a][pos_b] = std::max(sub_sols[pos_a + 1][pos_b],
37+
sub_sols[pos_a][pos_b + 1]);
4338
}
4439
}
4540
}
4641

47-
cout << str1 << "\n";
48-
cout << str2 << "\n";
42+
return sub_sols[0][0];
43+
}
44+
45+
struct TestCase {
46+
const std::string str_a;
47+
const std::string str_b;
48+
const std::size_t common_string_len;
49+
50+
TestCase(const std::string& in_str_a, const std::string& in_str_b,
51+
const std::size_t in_common_string_len)
52+
: str_a(in_str_a),
53+
str_b(in_str_b),
54+
common_string_len(in_common_string_len) {}
55+
};
56+
57+
std::vector<TestCase> get_test_cases() {
58+
return {TestCase("", "", 0),
59+
TestCase("ab", "ab", 2),
60+
TestCase("ab", "ba", 1),
61+
TestCase("", "xyz", 0),
62+
TestCase("abcde", "ace", 3),
63+
TestCase("BADANA", "ANADA", 3),
64+
TestCase("BADANA", "CANADAS", 3),
65+
TestCase("a1a234a5aaaa6", "A1AAAA234AAA56AAAAA", 6),
66+
TestCase("123x", "123", 3),
67+
TestCase("12x3x", "123", 3),
68+
TestCase("1x2x3x", "123", 3),
69+
TestCase("x1x2x3x", "123", 3),
70+
TestCase("x12x3x", "123", 3)};
71+
}
72+
73+
void test_longest_common_string_length() {
74+
for (const auto& cur_tc : get_test_cases()) {
75+
assert(longest_common_string_length(cur_tc.str_a, cur_tc.str_b) ==
76+
cur_tc.common_string_len);
77+
}
78+
}
79+
80+
void test_longest_common_string_length_is_symmetric() {
81+
for (const auto& cur_tc : get_test_cases()) {
82+
assert(longest_common_string_length(cur_tc.str_b, cur_tc.str_a) ==
83+
cur_tc.common_string_len);
84+
}
85+
}
86+
87+
/**
88+
* @brief reverses a given string
89+
* @param in_str input string
90+
* @return the string in which the characters appear in the reversed order as in
91+
* in_str
92+
*/
93+
std::string reverse_str(const std::string& in_str) {
94+
return {in_str.rbegin(), in_str.rend()};
95+
}
4996

50-
cout << "longest string size = " << ma /*<<" "<<indi<<" "<<indj*/ << "\n";
51-
for (i = indi - 3; i < indi; i++) cout << str1[i];
52-
cout << "\n";
97+
void test_longest_common_string_length_for_reversed_inputs() {
98+
for (const auto& cur_tc : get_test_cases()) {
99+
assert(longest_common_string_length(reverse_str(cur_tc.str_a),
100+
reverse_str(cur_tc.str_b)) ==
101+
cur_tc.common_string_len);
102+
}
103+
}
104+
105+
int main() {
106+
test_longest_common_string_length();
107+
test_longest_common_string_length_is_symmetric();
108+
test_longest_common_string_length_for_reversed_inputs();
109+
return 0;
53110
}

0 commit comments

Comments
 (0)