- Data Structure
- Networking
- RDBMS
- Operating System
- Java
- MS Excel
- iOS
- HTML
- CSS
- Android
- Python
- C Programming
- C++
- C#
- MongoDB
- MySQL
- Javascript
- PHP
- Physics
- Chemistry
- Biology
- Mathematics
- English
- Economics
- Psychology
- Social Studies
- Fashion Studies
- Legal Studies
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Generate all possible strings formed by replacing letters with given respective symbols
Generating all possible strings is to replace a character of a string with a respective symbol and produce all possible strings. We will be given a string ‘s’ of size ‘N’ and an unordered map ‘mp’ of a pair of characters of size ‘M’. Here we can replace the mp[i][0] with mp[i][1] in the string ‘s’ and by doing this our task is to generate all possible strings.
Sample Examples
Input: s = “xyZ”, mp = {‘x’ : ‘$’, ‘y’ : ‘#’, ‘Z’ : ‘^’} Output: xyZ xy^ x#Z z#^ $yZ $y^ $#Z $#^
Explanation − In the above example, there are a total 8 strings generated.
Input: s = “pQ”, mp = {‘p’ : ‘#’, ‘Q’ : ‘$’} Output: pQ #Q p$ #$
Explanation − In the above example, there are a total of 4 strings generated.
Input: s = “w”, mp = {‘w’ : ‘#’} Output: w #
Explanation − In the above example, there are a total of 2 strings generated.
Approach
In this approach, we will use the concept of brute force to find all the combinations which are possible.
First, we will create a function that will take a string, current index, and the given map as the parameters and return type will be void.
In the function, we will define the base condition in which the current index is equal to the size of the string, then we will print that string and return from the function.
Otherwise, we will have two choices one is to don’t change the current index and move to the next which will always be an option.
The second choice is only possible if the current character has any replacement. If the replacement exists then we will call to the replacement.
After that we will return from the function and it will automatically produce all the required results.
Let’s discuss the code of the above approach for better understanding.
Example
#include <bits/stdc++.h> using namespace std; // Function to generate all possible strings by replacing the characters with paired symbols void possibleStrings(string str, int idx, unordered_map<char, char> mp){ if (idx == str.size()) { cout << str << endl; return; } // Function call with the idx-th character not replaced possibleStrings(str, idx + 1, mp); // Replace the idx-th character str[idx] = mp[str[idx]]; // Function call with the idx-th character replaced possibleStrings(str, idx + 1, mp); return; } int main(){ string str = "xyZ"; unordered_map<char, char> mp; mp['x'] = '$'; mp['y'] = '#'; mp['Z'] = '^'; mp['q'] = '&'; mp['2'] = '*'; mp['1'] = '!'; mp['R'] = '@'; int idx = 0; // Call 'possibleStrings' function to generate all possible strings //Here in the 'possible strings' function, we have passed string 'str', index 'idx', and map 'mp' possibleStrings(str, idx, mp); return 0; }
Output
xyZ xy^ x#Z x#^ $yZ $y^ $#Z $#^
Time and Space Complexity
The time complexity of the above code is O(N*2^N) because we have just back traversed over the N elements and Where N is the size of the string ‘s’.
The space complexity of the above code is O(N*N), as we are sending the string as complete and there could be N copies of the string that exists at the same time.
Back Tracking
In the previous approach, we were sending the string without the pointer which leads to taking a lot of space. To reduce the space and time complexity we will use the concept of the backtracking.
Example
#include <bits/stdc++.h> using namespace std; // Function to generate all possible strings by replacing the characters with paired symbols void possibleStrings(string& str, int idx, unordered_map<char, char> mp){ if (idx == str.size()) { cout << str << endl; return; } // Function call with the idx-th character not replaced possibleStrings(str, idx + 1, mp); // storing the current element char temp = str[idx]; // Replace the idx-th character str[idx] = mp[str[idx]]; // Function call with the idx-th character replaced possibleStrings(str, idx + 1, mp); // backtracking str[idx] = temp; return; } int main(){ string str = "xyZ"; unordered_map<char, char> mp; mp['x'] = '$'; mp['y'] = '#'; mp['Z'] = '^'; mp['q'] = '&'; mp['2'] = '*'; mp['1'] = '!'; mp['R'] = '@'; int idx = 0; // Call 'possibleStrings' function to generate all possible strings //Here in the 'possible strings' function, we have passed string 'str', index 'idx', and map 'mp' possibleStrings(str, idx, mp); return 0; }
Output
xyZ xy^ x#Z x#^ $yZ $y^ $#Z $#^
Time and Space Complexity
The time complexity of the above code is O(N*2^N) because we have just back traversed over the N elements and Where N is the size of the string ‘s’.
The space complexity of the above code is O(N), as we are sending the address of the string makes only maximum N stacks going down.
Conclusion
In this tutorial, we have implemented a program to generate all possible strings formed by replacing letters with given respective symbols. Here we have seen the backtracking approach and the time complexity of the code is O(N*2^N), where N is the size of the string, and space complexity is the same as the time complexity. To reduce the space complexity, we have implemented the backtracking process.