Search code examples
javastringalgorithmstringbuilderexpansion

Expansion on given string according to number * contents of the parentheses


I am trying to take a given string and when there is a number before parentheses then what's inside the parentheses gets repeated that number of times. I thought about using StringBuilder and built this function but I'm not sure how to get the inside of the parentheses repeated. example- 3(ab) - result would be ababab , example- 3(b(2(c))) result would be bccbccbcc in the function I built here it repeats the parentheses and not the contents of the parentheses.

  public static String solve(String s){
    StringBuilder sb = new StringBuilder();
    int repeat = 0;
    for (char c : s.toCharArray()) {
        if (Character.isDigit(c)) {
            repeat = repeat * 10 + Character.getNumericValue(c);
        } else {
            while (repeat > 0) {
                sb.append(c);
                repeat--;
            }
            sb.append(c);
        }
    }
    return sb.toString();
    }
}

Solution

  • Pretty much the same answer as @SerialLazers, but in java and with a bit of debugging-output to see how the code behaves:

    public static String solve(String s)
    {
        Stack<Integer> countStack = new Stack<>();   // stack for counting
        Stack<StringBuilder> stubs = new Stack<>();  // stack for parts of the string that were processed
        stubs.push(new StringBuilder());
        
        int count = 0;
        for(char c : s.toCharArray())
        {
            System.out.println(Character.toString(c) + "   " + count + "   " + countStack + stubs);
            
            if(Character.isDigit(c))
            {
                // part of a count (assumes digits are never part of the actual output-string)
                count = count * 10 + (c - '0');
            }
            else if(c == '(')
            {
                // encountered the start of a new repeated group
                if(count == 0)
                    // no count specified, assume a count of one
                    countStack.push(1);
                else
                    // push the count for this group
                    countStack.push(count);
    
                // push a new stringbuilder that will contain the new group
                stubs.push(new StringBuilder());
                count = 0;  // reset count
            }
            else if(c == ')')
            {
                // group terminated => repeat n times and append to new group one above
                String tmp = stubs.pop().toString();
                int ct = countStack.pop();
                
                for(int i = 0; i < ct; i++)
                    stubs.peek().append(tmp);
            }
            else
            {
                // just a normal character, append to topmost group
                stubs.peek().append(c);
                count = 0;
            }
        }
        
        // if the string was valid there's only the output-string left on the stubs-list
        return stubs.peek().toString();
    }
    

    Output:

    3   0   [][]
    (   3   [][]
    b   0   [3][, ]
    (   0   [3][, b]
    2   0   [3, 1][, b, ]
    (   2   [3, 1][, b, ]
    c   0   [3, 1, 2][, b, , ]
    )   0   [3, 1, 2][, b, , c]
    )   0   [3, 1][, b, cc]
    )   0   [3][, bcc]
    

    Returns:

    bccbccbcc