首页 > 解决方案 > 根据括号的数字 * 内容扩展给定字符串

问题描述

我试图取一个给定的字符串,当括号前有一个数字时,括号内的内容会重复该次数。我考虑过使用 StringBuilder 并构建了这个函数,但我不确定如何重复括号的内部。示例- 3(ab) - 结果将是 ababab ,示例- 3(b(2(c))) 结果将是我在这里构建的函数中的 bccbccbcc 它重复括号而不是括号的内容。

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

标签: javastringalgorithmstringbuilderexpansion

解决方案


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

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.Pairjava.util.AbstractMap.SimpleEntry其他的。

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

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

推荐阅读