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