Algorithms_in_C++ 1.0.0
Set of algorithms implemented in C++.
Loading...
Searching...
No Matches
abbreviation.cpp File Reference

Implementation of Abbrievation More...

#include <cassert>
#include <iostream>
#include <string>
#include <vector>
Include dependency graph for abbreviation.cpp:

Namespaces

namespace  dynamic_programming
 Dynamic Programming algorithms.
 
namespace  abbreviation
 Functions for Abbreviation implementation.
 

Functions

bool dynamic_programming::abbreviation::abbreviation_recursion (std::vector< std::vector< bool > > *memo, std::vector< std::vector< bool > > *visited, const std::string &str, const std::string &result, uint32_t str_idx=0, uint32_t result_idx=0)
 Recursive Dynamic Programming function.
 
bool dynamic_programming::abbreviation::abbreviation (const std::string &str, const std::string &result)
 Iterative Dynamic Programming function.
 
static void test ()
 Self test-implementations.
 
int main ()
 Main function.
 

Detailed Description

Implementation of Abbrievation

Given two strings, a and b, determine if it's possible to make a equal to b You can perform the following operations on the string a:

  1. Capitalize zero or more of a's lowercase letters.
  2. Delete all of the remaining lowercase letters in a.

Algorithm

The idea is in the problem statement itself: iterate through characters of string a and b (for character indexes i and j respectively):

  1. If a[i] and b[j] are equal, then move to next position
  2. If a[i] is lowercase of b[j], then explore two possibilities: a. Capitalize a[i] or b. Skip a[i]
  3. If the a[i] is not uppercase, just discard that character, else return false

Time Complexity: (O(|a|*|b|)) where |a| => length of string a

Author
Ashish Daulatabad

Function Documentation

◆ abbreviation()

bool dynamic_programming::abbreviation::abbreviation ( const std::string & str,
const std::string & result )

Iterative Dynamic Programming function.

Returns whether s can be converted to t with following rules: a. Capitalize zero or more of s's lowercase letters from string s b. remove all other lowercase letters from string s Note: The transition states for iterative is similar to recursive as well

Parameters
strgiven string, which might not be abbreivated
resultresultant abbreivated string
Returns
false if string str cannot be converted to result
true if string str can be converted to result
118 {
120 str.size() + 1, std::vector<bool>(result.size() + 1, false));
121
122 for (uint32_t i = 0; i <= str.size(); ++i) {
123 memo[i][0] = true;
124 }
125 for (uint32_t i = 1; i <= result.size(); ++i) {
126 memo[0][i] = false;
127 }
128 for (uint32_t i = 1; i <= str.size(); ++i) {
129 for (uint32_t j = 1; j <= result.size(); ++j) {
130 if (str[i - 1] == result[j - 1]) {
131 memo[i][j] = memo[i - 1][j - 1];
132 } else if (str[i - 1] - 32 == result[j - 1]) {
133 memo[i][j] = (memo[i - 1][j - 1] || memo[i - 1][j]);
134 } else {
135 if (str[i - 1] >= 'A' && str[i - 1] <= 'Z') {
136 memo[i][j] = false;
137 } else {
138 memo[i][j] = memo[i - 1][j];
139 }
140 }
141 }
142 }
143 return memo.back().back();
144}
uint64_t result(uint64_t n)
Definition fibonacci_sum.cpp:76
T size(T... args)
Here is the call graph for this function:

◆ abbreviation_recursion()

bool dynamic_programming::abbreviation::abbreviation_recursion ( std::vector< std::vector< bool > > * memo,
std::vector< std::vector< bool > > * visited,
const std::string & str,
const std::string & result,
uint32_t str_idx = 0,
uint32_t result_idx = 0 )

Recursive Dynamic Programming function.

Returns whether s can be converted to t with following rules: a. Capitalize zero or more of a's lowercase letters from string s b. remove all other lowercase letters from string s

Parameters
memoTo store the result
visitedboolean to check if the result is already computed
strgiven string, which might not be abbreivated
resultresultant abbreivated string
str_idxindex for string str, helpful for transitions
result_idxindex for string result, helpful for transitions
Returns
false if string str cannot be converted to result
true if string str can be converted to result

(str[i] == result[j]): if str char at position i is equal to result char at position j, then s character is a capitalized one, move on to next character str[i] - 32 == result[j]: if str[i] character is lowercase of result[j] then explore two possibilites:

  1. convert it to capitalized letter and move both to next pointer (i + 1, j + 1)
  2. Discard the character (str[i]) and move to next char (i + 1, j)
61 {
62 bool ans = memo->at(str_idx).at(result_idx);
63 if (str_idx == str.size() && result_idx == result.size()) {
64 return true;
65 } else if (str_idx == str.size() && result_idx != result.size()) {
66 // result `t` is not converted, return false
67 return false;
68 } else if (!visited->at(str_idx).at(result_idx)) {
69 /**
70 * `(str[i] == result[j])`: if str char at position i is equal to
71 * `result` char at position j, then s character is a capitalized one,
72 * move on to next character `str[i] - 32 == result[j]`:
73 * if `str[i]` character is lowercase of `result[j]` then explore two
74 * possibilites:
75 * 1. convert it to capitalized letter and move both to next pointer
76 * `(i + 1, j + 1)`
77 * 2. Discard the character `(str[i])` and move to next char `(i + 1,
78 * j)`
79 */
80 if (str[str_idx] == result[result_idx]) {
81 ans = abbreviation_recursion(memo, visited, str, result,
82 str_idx + 1, result_idx + 1);
83 } else if (str[str_idx] - 32 == result[result_idx]) {
84 ans = abbreviation_recursion(memo, visited, str, result,
85 str_idx + 1, result_idx + 1) ||
86 abbreviation_recursion(memo, visited, str, result,
87 str_idx + 1, result_idx);
88 } else {
89 // if `str[i]` is uppercase, then cannot be converted, return
90 // `false`
91 // else `str[i]` is lowercase, only option is to discard this
92 // character
93 if (str[str_idx] >= 'A' && str[str_idx] <= 'Z') {
94 ans = false;
95 } else {
96 ans = abbreviation_recursion(memo, visited, str, result,
97 str_idx + 1, result_idx);
98 }
99 }
100 }
101 (*memo)[str_idx][result_idx] = ans;
102 (*visited)[str_idx][result_idx] = true;
103 return (*memo)[str_idx][result_idx];
104}
bool abbreviation_recursion(std::vector< std::vector< bool > > *memo, std::vector< std::vector< bool > > *visited, const std::string &str, const std::string &result, uint32_t str_idx=0, uint32_t result_idx=0)
Recursive Dynamic Programming function.
Definition abbreviation.cpp:58
T at(T... args)
Here is the call graph for this function:

◆ main()

int main ( void )

Main function.

Returns
0 on exit
191 {
192 test(); // run self-test implementations
193 return 0;
194}
static void test()
Self test-implementations.
Definition abbreviation.cpp:152
Here is the call graph for this function:

◆ test()

static void test ( )
static

Self test-implementations.

Returns
void
152 {
153 std::string s = "daBcd", t = "ABC";
155 std::vector<bool>(t.size() + 1, false)),
156 visited(s.size() + 1, std::vector<bool>(t.size() + 1, false));
157
158 assert(dynamic_programming::abbreviation::abbreviation_recursion(
159 &memo, &visited, s, t) == true);
160 assert(dynamic_programming::abbreviation::abbreviation(s, t) == true);
161 s = "XXVVnDEFYgYeMXzWINQYHAQKKOZEYgSRCzLZAmUYGUGILjMDET";
162 t = "XXVVDEFYYMXWINQYHAQKKOZEYSRCLZAUYGUGILMDETQVWU";
164 s.size() + 1, std::vector<bool>(t.size() + 1, false));
165
167 s.size() + 1, std::vector<bool>(t.size() + 1, false));
168
169 assert(dynamic_programming::abbreviation::abbreviation_recursion(
170 &memo, &visited, s, t) == false);
171 assert(dynamic_programming::abbreviation::abbreviation(s, t) == false);
172
173 s = "DRFNLZZVHLPZWIupjwdmqafmgkg";
174 t = "DRFNLZZVHLPZWI";
175
177 s.size() + 1, std::vector<bool>(t.size() + 1, false));
178
180 s.size() + 1, std::vector<bool>(t.size() + 1, false));
181
182 assert(dynamic_programming::abbreviation::abbreviation_recursion(
183 &memo, &visited, s, t) == true);
184 assert(dynamic_programming::abbreviation::abbreviation(s, t) == true);
185}
Here is the call graph for this function: