0

因此,如果我有一个用括号括起来的表达式,括号之间或括号之外的任何内容,我怎样才能删除最外面的一对括号,使用递归并调用 parseFactor (每次我看到一组括号我调用 parseFactor)?由于这非常模糊,我会给你一个例子来说明我的意思。以这个为例(这不是我要解决的具体问题,只是一个一般性的想法):
如果我有表达

((4+1)*1) + 5

我想将其分解,以便我首先得到(4+1)*1(第一对括号中的内容)。然后,再次调用 parseFactor 函数,因为我看到另一组括号,然后调用 parseExpression 的 parseFactor 将使用递归进行内部计算。所以这意味着我得到5*1. 然后我使用函数 parseTerm 和 get 进行计算5。一旦我退出递归,我就会5+5调用另一个名为 parseExpression 的函数,它将计算 5+5 并返回 10。

目前,我Matcher m = Pattern.compile("\\((.*)").matcher(expr)).find()在 parseFactor 中使用,然后将结果分组以删除第一个括号,引导我使用(4+1)*1) + 5. 我再次调用 parseFactor 得到 4+1)*1) + 5。问题是我不知道如何去掉外括号。如果有人需要,这是我的代码供参考:

else if(Pattern.matches("\\(.*", expr)){
    (m = Pattern.compile("\\((.*)").matcher(expr)).find();
    String save = m.group(1);
    (m = Pattern.compile("\\)(.*)").matcher(expr)).find();
    String remainder = m.group(1);
    int length = save.length();
    int rLength = remainder.length();
    save = save.substring(0, length - (rLength));
    expr = parseExpr(save);
    int i = findInt(expr);
    String value = Integer.toString(i);
    expr = value + remainder;
    (m = Pattern.compile("\\)(.*)").matcher(save)).find();
}

其中 expr 是要解析、分解和计算的字符串。这段代码来自我的 parseExpression 函数。findInt() 只返回它在字符串中找到的第一个整数。

编辑:我必须使用正则表达式。

4

4 回答 4

0

正则表达式对于这种操作来说有点过头了。由于JDK1.6,您可以使用内置的Javascript engine. 如果可能,请尝试使用它。

使用ScriptEngine.eval(String)方法基本上可以实现如下。

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "((4+1)*1) + 5";
System.out.println(engine.eval(foo));
于 2013-02-01T07:38:17.523 回答
0

基本上,使用正则表达式对您的意图是错误的,因为您正在处理嵌套结构,即递归。而正则表达式无法做到这一点。为了解释这一点,您首先应该了解有限自动机(它是正则表达式基础的数据结构)除了它所处的状态之外没有内存,如果您有任意深度的嵌套,您需要一个任意大的自动机,它与有限自动机的概念相冲突。

但是有一个非常简单的算法可以完成你的工作。

于 2013-02-01T07:49:31.780 回答
0

公共类 T_1{

String c[];
Stack<String> s1 = new Stack<String>();
Stack<String> s2 = new Stack<String>();
int top = 0;

/**
 * Description:构造函数
 * 
 * @param expression
 *            :表达式字符串
 */
public T_1(String expression) {
    ArrayList<String> al = new ArrayList<String>();
    char chare[] = expression.toCharArray();
    int count = 0;
    int i = 0;
    int start = 0;
    while (count < chare.length) {
        if (!judgeNum(new String(new char[] { chare[count] }))) {
            if (i != 0) {
                char c1[] = new char[i];
                System.arraycopy(chare, start, c1, 0, i);
                al.add(new String(c1));
            }
            al.add(new String(new char[] { chare[count] }));
            i = 0;
            start = count + 1;
        } else {
            i++;
        }
        count++;
    }
    if (judgeNum(new String(new char[] { chare[--count] }))) {
        al.add(new String(new char[] { chare[count] }));
    }
    // c=(String[])(al.toArray());
    System.out.println(al.toString());
    c = new String[al.size()];
    i = 0;
    for (Object o : al.toArray()) {
        c[i++] = o.toString();
    }
}

/**
 * Description:转换,c为中缀表达式
 */
public void transition() {
    int i = 0;
    while (i < c.length) {
        if (s1.empty()) {
            s1.push(c[i]);
        } else {
            if (judgeNum(c[i])) {
                s1.push(c[i]);
            } else if (judgeOperate(c[i])) {
                if (s2.isEmpty()) {
                    s2.push(c[i]);
                } else if (judgeLP(s2.peek())) {
                    s2.push(c[i]);
                } else if (judgePriority(c[i], s2.peek())) {
                    s2.push(c[i]);
                } else {
                    s1.push(s2.pop());
                    while (!s2.isEmpty() && !s2.peek().equals("(")) {
                        if (!judgePriority(c[i], s2.peek())) {
                            s1.push(s2.pop());
                        } else {
                            break;
                        }
                    }
                    s2.push(c[i]);
                }
            } else if (judgeLP(c[i])) {
                s2.push(c[i]);
            } else if (judgeRP(c[i])) {
                while (true) {
                    String c_1 = s2.pop();
                    if (!judgeLP(c_1)) {
                        s1.push(c_1);
                        System.out.println("c_1" + c_1);
                    } else {
                        break;
                    }
                }
            }
        }
        i++;
    }
    while (!s2.isEmpty()) {
        String c_1 = s2.pop();
        if (!judgeLP(c_1)) {
            s1.push(c_1);
        }
    }
}

/**
 * 
 * @param c
 * @return:是否是数字
 */
public boolean judgeNum(String c) {
    try {
        Integer.parseInt(c);
        return true;
    } catch (Exception e) {
        return false;
    }

}

/**
 * 
 * @param c
 * @return:是否是运算符
 */
public boolean judgeOperate(String c) {
    if (c.equals("+") || c.equals("-") || c.equals("*") || c.equals("/")) {
        return true;
    }
    return false;
}

/**
 * 
 * @param c
 * @return:是否是左括号
 */
public boolean judgeLP(String c) {
    if (c.equals("(")) {
        return true;
    }
    return false;
}

/**
 * 
 * @param c
 * @return:是否是右括号
 */
public boolean judgeRP(String c) {
    if (c.equals(")")) {
        return true;
    }
    return false;
}

/**
 * 
 * @param a
 * @param b
 * @return:是否a的优先级大于b
 */
public boolean judgePriority(String a, String b) {
    if ((a.equals("*") || a.equals("/"))
            && (b.equals("+") || b.equals("-"))) {
        return true;
    }
    return false;
}

/**
 * 运算
 */
public void operate() {
    while (!s1.isEmpty()) {
        s2.push(s1.pop());
    }
    /*
     * while(!judgeNum(s2.peek())){ s1.push(s2.pop()); }
     */
    System.out.println(s1.toString());
    System.out.println(s2.toString());
    while (!s2.isEmpty()) {
        String s = s2.pop();
        if (judgeNum(s)) {
            s1.push(s);
        } else {
            String a = s1.pop();
            String b = s1.pop();
            s1.push(operate_(b, a, s));
            System.out.println(s1.peek());
        }
    }
    System.out.println(s1.pop());
}

public String operate_(String a, String b, String c) {
    int ia = Integer.parseInt(a);
    int ib = Integer.parseInt(b);
    if (c.equals("+")) {
        return String.valueOf(ia + ib);
    } else if (c.equals("-")) {
        return String.valueOf(ia - ib);
    } else if (c.equals("*")) {
        return String.valueOf(ia * ib);
    } else if (c.equals("/")) {
        return String.valueOf(ia / ib);
    }
    return "";
}

public static void main(String[] args) {
    String s = JOptionPane.showInputDialog("请输入表达式!");
    T_1 t = new T_1(s);// "1+2+3*1+(2-1*4)*2+2"
    t.transition();
    t.operate();
}

}

于 2013-02-01T08:54:57.160 回答
0

以下正则表达式应匹配括号组,其中包含任何内容:

\\(.*\\)

注意:双反斜杠是因为 Java 转义字符,正则表达式实际上是“(。*)”,没有引号。

但是,您似乎正在尝试解析表达式,而正则表达式不是正确的工具,因此您应该考虑使用解析器。Java 中无法通过正则表达式来保证括号平衡之类的事情,因此很难保证表达式的正确性,甚至不可能。

于 2013-02-01T07:41:55.287 回答