import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.util.Stack; /** * input : abbaba4x[a]bb3x[abaa2x[bab]] * <p> * output : abbabaaaaabbabaababbababaababbababaababbab * <p> * Created by kiyan on 6/3/16. */ public class StringDecompression { private StringDecompression sd; /** * */ public String decompress(String s) { StringBuilder res = new StringBuilder(); StringBuilder nested = new StringBuilder(); Stack<String> stack = new Stack<>(); int i = 0; while (i < s.length()) { char c = s.charAt(i); if (Character.isDigit(c)) { // Save pattern in a stack String pattern = s.substring(i, i + 2); // Assume that only 1 digit before x int j = i + 3; while (j < s.length() && Character.isLetter(s.charAt(j))) { pattern += s.charAt(j); j++; } i = j - 1; stack.push(pattern); } else if (c == ']') { // Pop pattern from stack String[] pop = stack.pop().split("x"); String pattern = ""; for (int j = 0; j < Integer.parseInt(pop[0]); j++) { pattern += pop[1] + nested.toString(); } nested.setLength(0); // Clear string builder nested.append(pattern); if (stack.empty()) { res.append(nested.toString()); nested.setLength(0); } } else { res.append(c); } i++; } return res.toString(); } @Before public void setUp() { sd = new StringDecompression(); } @Test public void testExamples() { String res = sd.decompress("abbaba4x[a]bb3x[abaa2x[bab]]"); Assert.assertEquals("abbabaaaaabbabaababbababaababbababaababbab", res); } @After public void tearDown() { sd = null; } }