为什么不能转义为替换所有括号而工作的字符?

时间:2017-10-05 19:12:28

标签: java regex escaping

我尝试用对面的支架替换所有支架,因为我在Hackerrank.com上解决了编码挑战here.

我认为有一个解决方案可以解决这个挑战,但我似乎无法让所有功能替换为我的功能。我尝试使用Pattern.quote(String)以及转义反斜杠,但由于某种原因,我的括号不会被替换。

public class Solution {

    public static boolean isBalanced(String expression) {

        if(expression.length() %2 != 0) {
            return false;
        }
        else {

            int middle = expression.length() /2;
            String open = expression.substring(0,middle);
            String close = expression.substring(middle);

            close.replaceAll("\\)", "\\(");
            close.replaceAll(Pattern.quote("}"),"{");
            close.replaceAll(Pattern.quote("]"), "[");
            new StringBuilder(close).reverse().toString();

            if(close.equals(open))
                return true;
            else
                return false;
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int t = in.nextInt();
        for (int a0 = 0; a0 < t; a0++) {
            String expression = in.next();
            System.out.println( (isBalanced(expression)) ? "YES" : "NO" );
        }
    }
}

编辑:我在行new StringBuilder(close).reverse().toString();

之后用print语句测试了代码

输入:

3
{[()]}
{[(])}
{{[[(())]]}

输出:

)]}
NO
])}
NO
))]]}}
NO

2 个答案:

答案 0 :(得分:2)

Java中的

String对象是不可变的,因此在一个对象上执行替换命令不会更改源String,而是返回已修改的新String

让你的行像这样

close.replaceAll("\\)", "\\(");

看起来像这样

close = close.replaceAll("\\)", "\\(");

使用修改后的close对象更新String变量的值。

同样,此处创建的String将被分配给任何内容并将被丢弃:

new StringBuilder(close).reverse().toString();

您需要在某处分配创建的String,例如

close = new StringBuilder(close).reverse().toString();

答案 1 :(得分:2)

你的解决方案根本就是错误的,因为它容易出现误报。

具体来说,这个字符串会产生一个"YES",而字符串显然是不平衡的:

[({{(]

将字符串分成两半后,您将拥有"[({""{(]"。替换结束部分中的字符后,您将获得"{([",在撤消后变为"[({"。转换的结果与字符串的前半部分匹配,因此您的代码会错误地断定字符串中的括号是匹配的。