-1

我希望以下字符串由(相对于括号对)最外层运算符(在本例中:'+')分割:

1: "((20 + 20) + a)"
2: "(20 + ((20 + 20) + 20))

结果应该是这样的:

1: "((20 + 20) "         and           " a)"
2: "(20 "                and           " ((20 + 20) + 20))"
4

1 回答 1

2

你不能用正则表达式来做到这一点,但你可以尝试这样的事情:

// locations of top-level operators:
List<Integer> locations = new ArrayList<Integer>();

int level = 0;

for (int i = 0; i < str.length(); i++) {
    char c = str.charAt(i);

    if (c == '(') {
        level++;
    }
    else if (c == ')') {
        level--;
    } 
    else if ("+-*/".indexOf(c) >= 0 && level == 1) {
        locations.add(i);
    }
}

substring()然后,您可以使用和 中的任何内容“拆分”您的字符串locations


如果您总是想在最外层的运算符上进行拆分(例如,在+in上拆分(((a + 1)))),那么事情会变得有些棘手,但您的整体方法不必大幅改变。想到的一个想法是构建一个映射到字符串中位置的Map<OperatorData, Integer>(其中OperatorData包含操作符标记(例如+)的类和一个表示嵌套多远的 int 的类)。OperatorData可以Comparable基于嵌套级别。

OperatorData可能看起来像这样:

class OperatorData implements Comparable<OperatorData> {
    private String token;
    private int level;

    // constructor etc.

    @Override
    public int compareTo(OperatorData other) {
        return Integer.compare(level, other.level);
    }
}

然后,您可以浏览此映射并在嵌套级别最低的运算符上进行拆分。该方法可能如下所示:

// location of top-level operators:
Map<OperatorData, Integer> operators = new HashMap<>();

int level = 0;
int i = 0;
while (i < str.length()) {
    char c = str.charAt(i);

    if (c == '(') {
        level++;
    } else if (c == ')') {
        level--;
    } else if (isOperatorChar(c)) {
        final int index = i;
        StringBuilder token = new StringBuilder();
        token.append(c);

        while (isOperatorChar(c = str.charAt(i + 1))) {
            token.append(c);
            i++;
        }

        operators.put(new OperatorData(token.toString(), level), index);
    }

    i++;
}

// find smallest OperatorData in map
于 2013-08-21T22:20:58.330 回答