0

Arraylist を使用して方程式を個別の部分に分解することにより、任意の方程式 (単純なものから複雑なものまで) を文字列の形式で解くプログラムを作成しようとしています。最初に括弧をチェックしてから、検出できる最も深い括弧のセットに入り、内部の一連の演算をより強力な演算子から始めて解決し、次に進みます。かっこがなくなるまでチェックを続け、その後、残っているものを、より強力な演算子から始めます。arraylist に残った数が答えです。しかし、私は問題を抱えています。これが私のコードです:

import java.util.ArrayList;

public class StringEquation
{
    public static void main(String[] args) 
    {
        String s = "80+5+3*(11%(3*2)-(5+1)+6)-(10+10)+(2*2)*5";

        ArrayList<String> equation = new ArrayList<>();

        String ns = "";

        String b;

        int nsi;

        int si;

        int res = 0;

        boolean hasParen = false;

        for(int c=0; c<s.length(); c++)
        {
             b = s.substring(c,c+1);
             if("0".equals(b)||"1".equals(b)||"2".equals(b)||"3".equals(b)||"4".equals(b)||"5".equals(b)||"6".equals(b)||"7".equals(b)||"8".equals(b)||"9".equals(b))
             {
                 ns += b;
                 if(c==s.length()-1)
                 {
                     nsi = Integer.parseInt(ns);
                     equation.add(Integer.toString(nsi));
                 }
             }
             else if(("+".equals(b)||"-".equals(b)||"*".equals(b)||"/".equals(b)||"%".equals(b))&&!"".equals(ns))
             {
                nsi = Integer.parseInt(ns);
                equation.add(Integer.toString(nsi));
                equation.add(b);
                ns = "";
             }
             else if("(".equals(b))
             {
                 equation.add(b);
             }
             else if (")".equals(b))
             {
                nsi = Integer.parseInt(ns);
                equation.add(Integer.toString(nsi));
                equation.add(b);
                ns = "";
             }
             else if("+".equals(b)||"-".equals(b)||"*".equals(b)||"/".equals(b)||"%".equals(b))
             {
                 equation.add(b);
             }
        }

        while(true) //checks for parentheses
        {
            for(int d=0; d<equation.size(); d++)
            {
                if("(".equals(equation.get(d)))
                {
                    hasParen = true;
                }

                if(hasParen==true)
                {
                    while(!")".equals(equation.get(d)))
                    {
                        d++;
                    }
                    while(!"(".equals(equation.get(d)))
                    {
                        d--;
                    }
                    d++;

                    while(!")".equals(equation.get(d+1)))
                    {
                        if("-".equals(equation.get(d))) //checks to see if the String number on the Arraylist is negative
                        {
                            equation.remove(d);
                            si = Integer.parseInt(equation.get(d));
                            si *= -1;
                        }
                        else
                        {
                            si = Integer.parseInt(equation.get(d));
                        }

                        switch(equation.get(d+1))
                        {
                            case "*": si *= Integer.parseInt(equation.get(d+2)); 
                            equation.set(d, Integer.toString(si));
                            equation.remove(d+1);
                            equation.remove(d+2);
                                break;
                            case "/": si /= Integer.parseInt(equation.get(d+2));
                            equation.set(d, Integer.toString(si));
                            equation.remove(d+1);
                            equation.remove(d+2);
                                break;
                            case "%": si %= Integer.parseInt(equation.get(d+2));
                            equation.set(d, Integer.toString(si));
                            equation.remove(d+1);
                            equation.remove(d+2);
                                break;
                            default: d+=2;
                        }
                    }

                    while(!"(".equals(equation.get(d)))
                    {
                        d--;
                    }
                    d++;

                    while(!")".equals(equation.get(d+1)))
                    {
                        if("-".equals(equation.get(d))) //checks to see if the String number on the Arraylist is negative
                        {
                            equation.remove(d);
                            si = Integer.parseInt(equation.get(d));
                            si *= -1;
                        }
                        else
                        {
                            si = Integer.parseInt(equation.get(d));
                        }

                        switch(equation.get(d+1))
                        {
                            case "+": si += Integer.parseInt(equation.get(d+2)); 
                            equation.set(d, Integer.toString(si));
                            equation.remove(d+1);
                            equation.remove(d+2);
                                break;
                            case "-": si -= Integer.parseInt(equation.get(d+2));
                            equation.set(d, Integer.toString(si));
                            equation.remove(d+1);
                            equation.remove(d+2);
                                break;
                        }
                    }

                    if("(".equals(equation.get(d-1))&&")".equals(equation.get(d+1)))
                    {
                        equation.remove(d-1);
                        equation.remove(d+1);
                    }

                    hasParen = false;

                    d = 0;
                }
            }
            break;
        }

        for(int e=0; e<equation.size(); e+=2) //does all multiplication, division and modulus first
        {
            if("-".equals(equation.get(e))) //checks to see if the String number on the Arraylist is negative
            {
                equation.remove(e);
                si = Integer.parseInt(equation.get(e));
                si *= -1;
            }
            else
            {
                si = Integer.parseInt(equation.get(e));
            }

            switch(equation.get(e+1))
            {
                case "*": si *= Integer.parseInt(equation.get(e+2)); 
                equation.set(e, Integer.toString(si));
                equation.remove(e+1);
                equation.remove(e+2);
                    break;
                case "/": si /= Integer.parseInt(equation.get(e+2));
                equation.set(e, Integer.toString(si));
                equation.remove(e+1);
                equation.remove(e+2);
                    break;
                case "%": si %= Integer.parseInt(equation.get(e+2));
                equation.set(e, Integer.toString(si));
                equation.remove(e+1);
                equation.remove(e+2);
                    break;
                default: e+=2;
            }
        }

        for(int f=0; f<equation.size(); f+=2) //does the rest (addition and subtraction)
        {
            if("-".equals(equation.get(f))) //checks to see if the String number on the Arraylist is negative
            {
                equation.remove(f);
                si = Integer.parseInt(equation.get(f));
                si *= -1;
            }
            else
            {
                si = Integer.parseInt(equation.get(f));
            }

            switch(equation.get(f+1))
            {
                case "+": si += Integer.parseInt(equation.get(f+2)); 
                equation.set(f, Integer.toString(si));
                equation.remove(f+1);
                equation.remove(f+2);
                    break;
                case "-": si -= Integer.parseInt(equation.get(f+2));
                equation.set(f, Integer.toString(si));
                equation.remove(f+1);
                equation.remove(f+2);
                    break;
            }
        }

        System.out.print(equation.get(0)); //Arraylist should only have the answer of the string equation by this point.

        //The part below was to see if lines 25-59 had obtained the whole equation in seperate parts within the arraylist.

//        for(int i=0; i<equation.size(); i++)
//        {
//            System.out.print(equation.get(i));
//        }
//        System.out.println("\n");
    }
}

これを実行すると、次のエラーが表示されます。

Exception in thread "main" java.lang.NumberFormatException: For input string: "("
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:481)
    at java.lang.Integer.parseInt(Integer.java:527)
    at stringequationfull.StringEquationFull.main(StringEquationFull.java:87)
Java Result: 1

何か助けはありますか?

4

3 に答える 3

0

これには実際に解析/字句解析フレームワークを使用してから、解析ツリーの上に方程式ソルバーを実装する必要があります。

ここに出発点があります: Java で文法用の LALR パーサーを作成する方法は?

于 2013-04-11T14:58:14.160 に答える
0

Integer#parseIntのドキュメントを参照してください。

例外: NumberFormatException - 文字列に解析可能な整数が含まれていない場合。

表示されるエラー メッセージは非常に有益です。

を解析しようとしていますが"("、これは解析可能な整数ではありません。

デバッガーを使用すると、これを 1 分もかからずに解決できます。

于 2013-04-11T14:32:45.830 に答える
0

前述のように、「(」を整数として解析しようとしています。

しかし、これはあなたの主な問題ではありません。

主な問題は、不必要に推論するのが難しい巨大な巨大なコードの塊があることです。

文字列を配列リストではなくツリーのような構造に変換する必要があります。これにより、はるかに簡単でバグのない方法で計算を行うことができます。

あなたの問題は単純なので、このタスクにパーサージェネレーターを使用することはお勧めしません。(時間がかかりすぎます)。ただし、要件に合わせてデータ構造を設計する必要があります。

インスピレーションを得るために調べることができる数式用のパーサーがたくさんあります。

一般に、次のようなものがあります。

Class Statement{}

class AddStatement extends Statement{
    Statement lhs;
    Statement rhs;
}

Class constant extends Statement{
    int value;
}

サポートするすべての操作のクラスを作成し、入力をこの構造体に再帰的に解析する必要があります。適切に行えば、評価は簡単になります。

ガイダンスとして使用できる十分なリソースがオンラインで入手できるため、詳細には触れません。

上記のコードを続行したい場合は、コードを小さなチャンクに分割する方法を見つけて、デバッグしやすく、幸運を祈ることをお勧めします。

于 2013-04-11T15:16:06.860 に答える