Decode a String Recursively Encoded as Count followed by Substring


In this problem, we need to decode the given string by repeatedly adding the total count number of times.

We can have three different approaches to solving the problem, and we can use two stacks or one stack to solve the problem. Also, we can solve the problem without using the two stacks.

Problem statement − We have given a string str containing the opening and closing brackets, alphabetical and numeric characters. We need to decode the string recursively.

Here are the patterns or rules to decode the string.

  • <count>[chars] − The ‘chars’ should appear count times in the resultant string.

Sample examples

Input

str = "2[d]3[c2[n]]";

Output

ddcnncnncnn

Explanation 

  • First, we decode 2[n], and we get "2[d]3[cnn]".

  • Next, we decode 3[cnn]. So, we get “2[d]cnncnncnn”.

  • Next, we decode 2[d]. So, we get “ddcnncnncnn”.

Input

5[i]

Output

iiiii

Explanation − We get 5 ‘I’ when we decode the given string.

Input

3[fg]

Output

fgfgfg

Explanation − We get ‘fg’ 3 times when we decode the input string.

Approach 1

We will use the two stacks to solve the problem in this approach. When we get an opening bracket, we push it into the stack. Also, when we get numeric characters, we append all numeric characters to make a valid positive integer and add them to the integer stack. After that, we pop integers and characters from the stack when we get the closing bracket.

Algorithm

Step 1 − Define ‘instSt’ stack to store numbers and ‘strSt’ to store the string characters and opening brackets. Furthermore, initialize the ‘answer’ to store the resultant string and ‘tempStr’ to store the temporary string.

Step 2 − Start traversing the string.

Step 3 − Initialize the ‘num’ with 0 to store the number if the current character is numeric.

Step 3.1 − If the character at the pth index is a digit, traverse the string until we get an alphabetical character or bracket. In the loop, multiply the previous value of ‘num’ by 10, and add the current digit to it.

Step 3.2 − Increase the value of ‘p’ by 1.

Step 3.3 − Push the number value to the ‘instSt’ stack.

Step 4 − If the character at the pth index is closing bracket, follow the below steps.

Step 4.1 − Initialzie ‘temp_str’ with an empty string. After that, if ‘instSt’ is not empty, pop the top integer from the stack.

Step 4.2 − Now, use the loop until we get the opening bracket or stack becomes empty from the ‘strSt’ stack. Also, append characters to ‘temp_str’.

Step 4.3 − If we stopped pooping the character due to ‘[‘, remove it.

Step 4.4 − Next, we need to append the ‘temp_Str’ for ‘num’ times in the ‘answer’ string.

Step 4.5 − Insert each character of the ‘answer’ string in the ‘strSt’ stack, and reinitialize it with the empty string.

Step 5 − If the current character is opening bracket, follow the below steps.

Step 5.1 − If the previous character is a digit, push ‘[‘ to the stack ‘StrSt’. Otherwise, push ‘[‘ to the StrSt stack and 1 to the ‘instSt’ stack.

Step 6 − If we get an alphabetical character, push it to the ‘strSt’ stack.

Step 7 − At the end, use a loop to remove all characters from the ‘strSt’ stack, append to the ‘answer’ string, and return it.

Example

#include <bits/stdc++.h>
using namespace std;

string decodeTheString(string alpha) {
    stack<int> instSt;
    stack<char> StrSt;
    string tempStr = "", answer = "";
    // Iterate the string
    for (int p = 0; p < alpha.length(); p++) {
        int num = 0;
        // If we find the number, extract the number and push it to the stack
        if (alpha[p] >= '0' && alpha[p] <= '9') {
            // Making iterations until we get an alphabetic character
            while (alpha[p] >= '0' && alpha[p] <= '9') {
                num = num * 10 + alpha[p] - '0';
                p++;
            }
            p--;
            instSt.push(num);
        }
        // If the character at the pth index is closing bracket
        else if (alpha[p] == ']') {
            tempStr = "";
            num = 0;
            // Pop the number from the stack
            if (!instSt.empty()) {
                num = instSt.top();
                instSt.pop();
            }
            // Pop the character until we get the opening bracket
            while (!StrSt.empty() && StrSt.top() != '[') {
                tempStr = StrSt.top() + tempStr;
                StrSt.pop();
            }
            // remove the opening bracket
            if (!StrSt.empty() && StrSt.top() == '[')
                StrSt.pop();
            // Append string to answer for num times
            for (int j = 0; j < num; j++)
                answer = answer + tempStr;
            // Insert the updated string again into the stack
            for (int j = 0; j < answer.length(); j++)
                StrSt.push(answer[j]);
            answer = "";
        }
        // If the character at the pth index is an opening bracket
        else if (alpha[p] == '[') {
            if (alpha[p - 1] >= '0' && alpha[p - 1] <= '9') {
                StrSt.push(alpha[p]);
            } else {
                StrSt.push(alpha[p]);
                instSt.push(1);
            }
        } else {
            // Push alphabetic character in the string stack.
            StrSt.push(alpha[p]);
        }
    }
    // Pop all the elements, make a string, and return.
    while (!StrSt.empty()) {
        answer = StrSt.top() + answer;
        StrSt.pop();
    }
    return answer;
}
// starting code
int main() {
    string str = "2[d]3[c2[n]]";
    cout << "The resultant string after decoding it is - " << decodeTheString(str) << endl;
    return 0;
}

Output

The resultant string after decoding it is - ddcnncnncnn

Time complexity− O(n^2) as we traverse the string and keep pushing and popping elements to the stack.

Space complexity − O(n) to store elements in the stack.

Approach 2

We will solve the problem without using the stack in this approach. Also, we will use the reverse() method to reverse the string.

Algorithm

Step 1 − Start iterating the string.

Step 2 − If an ith character is ‘]’, push it to the ‘answer’ string. Otherwise, follow the below steps.

Step 3 − Initialize the ‘temp_Str’ with the empty string.

Step 4 − Keep traversing the ‘answer’ string until the string is empty or we find the ‘[‘ character. Also, keep popping the last character from the ‘answer’ string and append it to the ‘temp_Str’ string.

Step 5 − Reverse the ‘temp_Str’ string as we traverse back from where we find the ‘]’ bracket.

Step 6 − Remove the last character from the ‘answer’ string to remove the ‘[‘ character.

Step 7 − If the ‘answer’ string contains digits at the top, make an integer number using digits, and store it in the number variable.

Step 8 − Reverse the number string.

Step 9 − Use the stoi() method to convert a string to a number.

Step 10 − Append temp_Str string to answer string for ‘number’ times.

Step 11 − Return the ‘answer’ string.

Example

#include <bits/stdc++.h>
using namespace std;

string decodeTheString(string alpha) {
    string answer = "";
    // iterate the string characters
    for (int i = 0; i < alpha.length(); i++) {
        // for all other characters except the closing bracket
        if (alpha[i] != ']') {
            answer.push_back(alpha[i]);
        } else {
            // Extract the substring lying within the pair
            string temp_str = "";
            // Keep on popping characters until '[' is found.
            while (!answer.empty() && answer.back() != '[') {
                temp_str.push_back(answer.back());
                answer.pop_back();
            }
            // get original string by reversing the string
            reverse(temp_str.begin(), temp_str.end());
            // open bracket removal
            answer.pop_back();
            // get integer value before the '[' character
            string number = "";
            // get the number before opening bracket
            while (!answer.empty() && answer.back() >= '0' && answer.back() <= '9') {
                number.push_back(answer.back());
                answer.pop_back();
            }
            // reverse number string
            reverse(number.begin(), number.end());
            // convert string to integer
            int numInt = stoi(number);
            for (int p = 0; p < numInt; p++) {
                answer += temp_str;
            }
        }
    }
    return answer;
}
int main() {
    string str = "2[d]3[c2[n]]";
    cout << "The resultant string after decoding it is - " << decodeTheString(str) << endl;
    return 0;
}

Output

The resultant string after decoding it is − ddcnncnncnn

Time complexity− O(N^2) as we traverse the string and use the reverse() method inside the loop.

Space complexity − O(N) to store the number and temporary string.

Updated on: 14-Aug-2023

116 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements