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

パブリッククラス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

正規表現は、この種の操作にはやり過ぎです。以来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

次の正規表現は、括弧グループと一致する必要があります。

\\(.*\\)

注: 二重のバックスラッシュは、Java エスケープ文字によるものです。正規表現は実際には引用符なしの "(.*)" です。

ただし、式を解析しようとしているようで、正規表現はそのための適切なツールではないため、パーサーの使用を検討する必要があります。Java では正規表現を使用して括弧のバランスを確保することはできないため、式の正確性を確保することは非常に困難であり、おそらく不可能です。

于 2013-02-01T07:41:55.287 に答える