java—根据括号中的数字*内容对给定字符串进行扩展

bfnvny8b  于 2021-07-12  发布在  Java
关注(0)|答案(3)|浏览(291)

我试着取一个给定的字符串,当括号前有一个数字时,括号内的内容就会重复这个次数。我考虑过使用stringbuilder并构建这个函数,但我不知道如何重复括号的内部。示例-3(ab)-result将是ababab,示例-3(b(2(c)))result将是bcc在我在这里构建的函数中它重复括号而不是括号的内容。

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();
    }
}
rxztt3cl

rxztt3cl1#

与@serialazers的答案基本相同,但在java中,需要一些调试输出来查看代码的行为:

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();
}

输出:

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]

退货:

bccbccbcc
vsaztqbk

vsaztqbk2#

这个问题自然是递归的。保留您已经开始的方法,您可以编写如下内容。在实际代码中,我可能倾向于一种将标记化和解析分离的方法,这意味着我将执行两个单独的过程:第一个过程将输入字符串转换为标记,第二个过程从标记流生成输出。

public static Pair<String, Integer> solve(String s, int start) {
    int repeat = 0;
    String ret = "";

    for (int i = start; i < s.length(); i++) {
        final char c = s.charAt(i);

        if (Character.isDigit(c)) {
            repeat = repeat * 10 + Character.getNumericValue(c);
        } else if (c == '(') {
            final Pair<String, Integer> inner = solve(s, i + 1);
            // At least one repetition, even if no explicit `repeat` given.
            ret += inner.first;
            while (--repeat > 0) {
                ret += inner.first;
            }
            repeat = 0; // Ensure that `repeat` isn’t -1 after the loop.
            i = inner.second;
        } else if (c == ')') {
            return new Pair<>(ret, i);
        } else {
            ret += c;
        }
    }

    return new Pair<>(ret, s.length());
}

将此代码转换为使用单个 StringBuilder -为了避免多余的字符串副本-作为练习。
上面使用了一个简单的 Pair 助手类。由于java没有附带一个(groan),这里有一个非常简单的实现,可以与上面的代码一起使用;您也可以使用javafx的 javafx.util.Pair 或者 java.util.AbstractMap.SimpleEntry 或者别的什么。

static class Pair<T, U> {
    final T first;
    final U second;

    Pair(T f, U s) {
        first = f;
        second = s;
    }
}
mctunoxg

mctunoxg3#

您需要一个堆栈来维护从最内部到最外部容器所需操作的某种内存。
下面是python中的代码:

def parenthesis_printer(s):
    L = [""]   # maintains the stack of the string-containers
    N = [1]    # maintains the stack of the print-multiplier needed for the corresponding string-container
    nstr = ""
    for i in range(len(s)):
        if s[i].isnumeric():
            nstr += s[i]
        elif s[i] == '(':
            nstr = "1" if len(nstr) == 0 else nstr
            nval = int(nstr)
            N.append(nval)
            L.append("")
            nstr = ""
        elif s[i] == ')':
            nval = N.pop()
            lval = L.pop()
            lstr = "".join([lval for _ in range(nval)])
            L[-1] += lstr
        else:
            L[-1] += s[i]
    return L[-1]

print(parenthesis_printer("3(b(2(c)))"))

输出:

bccbccbcc

相关问题