Open In App

JavaScript Program to Decode a String Recursively Encoded as Count Followed by Substring

Last Updated : 05 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an encoded string, the encoding is done as follows: The string is divided into substrings. Each substring is followed by a number, representing the count of times that substring should be repeated.

The task is to decode this encoded string recursively and return the decoded string.

<count>[sub_str] ==> The substring 'sub_str' appears count times.

Examples:

Input : str[] = "2[ni]"
Output : nini
Input : str[] = "2[f2[k]]"
Output : fkkfkk
Input : str[] = "3[b2[ca]]"
Output : bcacabcacabcaca

Table of Content

Approach 1: Using two Stacks

  • Initialize two stacks: one for integers (let’s call it the integer stack) and the other for characters (the character stack).
  • Traverse the input string character by character.
  • When encountering a number, push it onto the integer stack.
  • If you encounter an alphabet character (from ‘a’ to ‘z’) or an open bracket (‘[‘), push it onto the character stack.
  • If a closing bracket (‘]’) is encountered, perform the following steps:
  • Pop characters from the character stack until an open bracket (‘[‘) is encountered.
  • Pop the top element from the integer stack, denoted as ‘n’.
  • Create a string by repeating the characters obtained in the previous step ‘n’ times.
  • Push each character of the generated string back onto the character stack.
  • Continue this process until the entire string is traversed.

Example:This example shows the use of the above-explained appraoch.

Javascript




// Javascript program to decode a string recursively
// encoded as count followed substring
  
// Returns decoded string for 'str'
function decode(str) {
    let integerstack = [];
    let stringstack = [];
    let temp = "",
        result = "";
  
    // Traversing the string
    for (let i = 0; i < str.length; i++) {
        let count = 0;
  
        // If number, convert it into number
        // and push it into integerstack.
        if (str[i] >= "0" && str[i] <= "9") {
            while (str[i] >= "0" && str[i] <= "9") {
                count = count * 10 + str[i] - "0";
                i++;
            }
  
            i--;
            integerstack.push(count);
        }
  
        // If closing bracket ']', pop element
        // until '[' opening bracket is not found
        // in the character stack.
        else if (str[i] == "]") {
            temp = "";
            count = 0;
  
            if (integerstack.length > 0) {
                count =
                    integerstack[integerstack.length - 1];
                integerstack.pop();
            }
  
            while (
                stringstack.length > 0 &&
                stringstack[stringstack.length - 1] != "["
            ) {
                temp =
                    stringstack[stringstack.length - 1] +
                    temp;
                stringstack.pop();
            }
  
            if (
                stringstack.length > 0 &&
                stringstack[stringstack.length - 1] == "["
            ) {
                stringstack.pop();
            }
  
            // Repeating the popped string 'temo'
            // count number of times.
            for (let j = 0; j < count; j++) {
                result = result + temp;
            }
  
            // Push it in the character stack.
            for (let j = 0; j < result.length; j++) {
                stringstack.push(result[j]);
            }
  
            result = "";
        }
  
        // If '[' opening bracket, push it
        // into character stack.
        else if (str[i] == "[") {
            if (str[i - 1] >= "0" && str[i - 1] <= "9") {
                stringstack.push(str[i]);
            } else {
                stringstack.push(str[i]);
                integerstack.push(1);
            }
        } else {
            stringstack.push(str[i]);
        }
    }
  
    // Pop all the element, make a
    // string and return.
    while (stringstack.length > 0) {
        result =
            stringstack[stringstack.length - 1] + result;
        stringstack.pop();
    }
  
    return result;
}
  
let str = "3[f2[jk]]";
console.log(decode(str));


Output

fjkjkfjkjkfjkjk

Approach 2: Without Stacks

Algorithm for better understanding.

  • Initialize an empty string to store the decoded output.
  • Traverse the input string character by character.
  • If the current character is not a closing bracket (‘]’), simply add it to the output string.
  • If the current character is a closing bracket (‘]’), it indicates the end of a substring. We need to extract the substring enclosed within the corresponding opening bracket (‘[‘) and determine the number of times it needs to be repeated. We’ll use a variable, let’s call it num, to store this count.
  • Once we have extracted num and substring, append substring to the output string num times. This replicates the decoding process where substring is repeated num times.
  • Continue steps 3-5 until we reach the end of the input string.
  • Finally, return the decoded string, which is the result after processing the entire input.

Example: Below is the implementation of the above approach.

Javascript




// Function to decode given encoded string
function decodeString(s) {
    let result = "";
  
    for (let i = 0; i < s.length; i++) {
        if (s[i] !== "]") {
            // If the current character is 
            // not a closing bracket,
            // append it to the result string.
            result += s[i];
        } else {
            // If the current character is 
            // a closing bracket:
  
            // Create a temporary string to 
            // store the substring within
            // the corresponding opening bracket.
            let temp = "";
            while (
                result.length > 0 &&
                result[result.length - 1] !== "["
            ) {
                // Keep popping characters from the 
                // result string and add them to the
                // temp string until we reach the opening bracket.
                temp = result[result.length - 1] + temp;
                result = result.slice(0, -1);
            }
  
            result = result.slice(0, -1); // Remove the opening bracket
  
            // Extract the preceding number and convert it to an integer.
            let num = "";
            while (
                result.length > 0 &&
                !isNaN(result[result.length - 1])
            ) {
                // Keep popping characters from the 
                // result string and add them to
                // num string
                // until we encounter a non-digit character.
                num = result[result.length - 1] + num;
                result = result.slice(0, -1);
            }
            let int_num = parseInt(num);
  
            // Append the substring to the result string,
            // repeat it to the required number of times.
            while (int_num--) {
                result += temp;
            }
        }
    }
  
    // Return the decoded string.
    return result;
}
  
// Driver code to test above function
let str = "2[1[a]2[b]]";
console.log(decodeString(str));


Output

abbabb


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads