4

これまでのところ、正常に機能する次のものがあります。これを行うにはおそらくもっと簡単な方法があると思いますが、私が変更/変更する必要があるのは、Matheqのトップメソッドです。Mathメソッドは、単一の数学演算を実行します。

+、-、*、および/を使用した単一の操作で機能します。

私の問題は、10-10 / 5 + 3などのより大きな方程式を解くことです。ただし、10/5 + 65*2は正しく解かれます。その理由は、各部分、数値、および演算が文字列配列に分割されるためです。各操作が完了すると、数値と操作がその方程式の結果に置き換えられます。もっと混乱しているように見えるかもしれませんが、私はこれ以上の方法を考えることができませんでした。他の方程式を解けない理由は、文字列を文字列配列にマップし直したためです。

文字列配列の例例 10-10/5 +3文字列={10、-、10、/、5、+、3}の場合、演算が最初に除算され、次に左から右に減算され、次に加算文字列= {8、8、2、2、2、 5、5}

これが私のコードです。誰かが私を助けてください:

REVISED が改訂され、上記で動作するようになりましたが、LONG方程式でまだ問題があります。簡単な例は、2 * 2 * 2 * 2を5で割ったものをうまく解くというものですが、10-2 * 2 * 2*2を5で割った値に変更すると間違った答えになります。

 public class Matheq {

String fnum = null;
String lnum = null;
String total = null;

public String Matheq(String mathoperation) {

    String mathoperation= "6 * 3 - 4 * 2";

    mathoperation = mathoperation.replaceAll(",", "");
    mathoperation = mathoperation.replaceAll("plus", "+");
    mathoperation = mathoperation.replaceAll("minus", "-");
    mathoperation = mathoperation.replaceAll("times", "*");
    mathoperation = mathoperation.replaceAll("divided by", "dividedby");
    mathoperation = mathoperation.replaceAll("percent of", "percentof");
    String[] splitstr = mathoperation.split(" ");
    while(splitstr.length>1){
    for(int i=0; i<splitstr.length; i++) {
        System.out.println("Get value: " + splitstr[i]);
        if(splitstr[i].indexOf("percentof") >= 0) {
        String buildit = splitstr[i-1] + " percent of " + splitstr[i+1];
        String done = math(buildit);
        System.out.println("Percentage operation: " + splitstr[i-1] + " percent of " + splitstr[i+1] + "=" + done);
        splitstr[i] = done;
        splitstr[i-1] = "";
        splitstr[i+1] = "";
        ArrayList<String> list = new ArrayList<String>();
        for(String s : splitstr){
            if(!s.equals("")){
                list.add(s);
            }
        }
        splitstr = list.toArray(new String[list.size()]);
        }
    }
    for(int i=0; i<splitstr.length; i++) {
        System.out.println("Get value: " + splitstr[i]);
        if(splitstr[i].indexOf("dividedby") >= 0) {
            String buildit = splitstr[i-1] + " divided by " + splitstr[i+1];
            String done = math(buildit);
            System.out.println("Division operation: " + splitstr[i-1] + " divided by " + splitstr[i+1] + "=" + done);
            splitstr[i] = done;
            splitstr[i-1] = "";
            splitstr[i+1] = "";
            ArrayList<String> list = new ArrayList<String>();
            for(String s : splitstr){
                if(!s.equals("")){
                    list.add(s);
                }
            }
            splitstr = list.toArray(new String[list.size()]);
        }
    }
    for(int i=0; i<splitstr.length; i++) {
        System.out.println("Get value: " + splitstr[i]);
        if(splitstr[i].indexOf("*") >= 0) {
            String buildit = splitstr[i-1] + " * " + splitstr[i+1];
            String done = math(buildit);
            System.out.println("Multiplication operation: "+ splitstr[i-1] + " * " + splitstr[i+1] + "=" + done);
            splitstr[i] = done;
            splitstr[i-1] = "";
            splitstr[i+1] = "";
            ArrayList<String> list = new ArrayList<String>();
            for(String s : splitstr){
                if(!s.equals("")){
                    list.add(s);
                }
            }
            splitstr = list.toArray(new String[list.size()]);
        }
    }
    for(int i=0; i<splitstr.length; i++) {
            System.out.println("Get value: " + splitstr[i]);
        if(splitstr[i].indexOf("+") >= 0) {
            String buildit = splitstr[i-1] + " + " + splitstr[i+1];
            String done = math(buildit);
            System.out.println("Addition operation: " + splitstr[i-1] + " + " + splitstr[i+1] + "=" + done);
            splitstr[i] = done;
            splitstr[i-1] = "";
            splitstr[i+1] = "";
            ArrayList<String> list = new ArrayList<String>();
            for(String s : splitstr){
                if(!s.equals("")){
                    list.add(s);
                }
            }
            splitstr = list.toArray(new String[list.size()]);
        }
    }
        for(int i=0; i<splitstr.length; i++) {
            System.out.println("Get value: " + splitstr[i]);
            if(splitstr[i].indexOf("-") >= 0) {
            String buildit = splitstr[i-1] + " - " + splitstr[i+1];
            String done = math(buildit);
            System.out.println("Subtraction operation: " + splitstr[i-1] + " - " + splitstr[i+1] + "=" + done);
            splitstr[i] = done;
            splitstr[i-1] = "";
            splitstr[i+1] = "";
            ArrayList<String> list = new ArrayList<String>();
            for(String s : splitstr){
                if(!s.equals("")){
                    list.add(s);
                }
            }
            splitstr = list.toArray(new String[list.size()]);
        }   
    }
    for(int i=0; i<splitstr.length; i++) {  
        System.out.println("Final operation: " + total + " " + splitstr[i]);
    }
    }
    return total;

}

private String math(String mathoperation) {
    // TODO Auto-generated method stub
    if(mathoperation.contains("percent of")){
        mathoperation = mathoperation.replaceAll("percent of", "%");
        int str = mathoperation.indexOf("%");
        System.out.println(str);
        fnum = mathoperation.substring(0, str-1);
        fnum = fnum.replaceAll(" ", "");
        fnum = "." + fnum;
        System.out.println(fnum);
        double intfnum = Double.parseDouble(fnum);
        System.out.println(intfnum);
        int lastind = mathoperation.length();
        System.out.println(lastind);
        lnum = mathoperation.substring(str+1, lastind);
        lnum = lnum.replaceAll(" ", "");
        System.out.println(lnum);
        double intlnum = Double.parseDouble(lnum);
        System.out.println(intlnum);
        double tot = intlnum * intfnum;
        System.out.println(tot);
        total = Double.toString(tot);
        if(total.length() == 3){
            total = total + "0";
        }
        if(total.length() > 5){
            total = total.substring(0, 4);
        }
        total = total.replace("0.", "");
        System.out.println("Total:" + total);
        } else 
    if(mathoperation.contains("-")){
        int str = mathoperation.indexOf("-");
        System.out.println(str);
        fnum = mathoperation.substring(0, str-1);
        fnum = fnum.replaceAll(" ", "");
        System.out.println(fnum);
        double intfnum = Double.parseDouble(fnum);
        System.out.println(intfnum);
        int lastind = mathoperation.length();
        System.out.println(lastind);
        lnum = mathoperation.substring(str+1, lastind);
        lnum = lnum.replaceAll(" ", "");
        System.out.println(lnum);
        double intlnum = Double.parseDouble(lnum);
        System.out.println(intlnum);
        double tot = intfnum - intlnum; 
        System.out.println(tot);
        total = Double.toString(tot);
        System.out.println(total);
        } else 
    if(mathoperation.contains("+")){
        int str = mathoperation.indexOf("+");
        System.out.println(str);
        fnum = mathoperation.substring(0, str-1);
        fnum = fnum.replaceAll(" ", "");
        System.out.println(fnum);
        double intfnum = Double.parseDouble(fnum);
        System.out.println(intfnum);
        int lastind = mathoperation.length();
        System.out.println(lastind);
        lnum = mathoperation.substring(str+1, lastind);
        lnum = lnum.replaceAll(" ", "");
        System.out.println(lnum);
        double intlnum = Double.parseDouble(lnum);
        System.out.println(intlnum);
        double tot = intfnum + intlnum; 
        System.out.println(tot);
        total = Double.toString(tot);
        System.out.println(total);
        } else 
    if(mathoperation.contains("*")){
    int str = mathoperation.indexOf("*");
    System.out.println(str);
    fnum = mathoperation.substring(0, str-1);
    fnum = fnum.replaceAll(" ", "");
    System.out.println(fnum);
    double intfnum = Double.parseDouble(fnum);
    System.out.println(intfnum);
    int lastind = mathoperation.length();
    System.out.println(lastind);
    lnum = mathoperation.substring(str+1, lastind);
    lnum = lnum.replaceAll(" ", "");
    System.out.println(lnum);
    double intlnum = Double.parseDouble(lnum);
    System.out.println(intlnum);
    double tot = intfnum * intlnum; 
    System.out.println(tot);
    total = Double.toString(tot);
    System.out.println(total);
    } else
    if(mathoperation.contains("divided by")){
    mathoperation = mathoperation.replaceAll("divided by", "/");
    int str = mathoperation.indexOf("/");
    System.out.println(str);
    fnum = mathoperation.substring(0, str-1);
    fnum = fnum.replaceAll(" ", "");
    System.out.println(fnum);
    double intfnum = Double.parseDouble(fnum);
    System.out.println(intfnum);
    int lastind = mathoperation.length();
    System.out.println(lastind);
    lnum = mathoperation.substring(str+1, lastind);
    lnum = lnum.replaceAll(" ", "");
    System.out.println(lnum);
    double intlnum = Double.parseDouble(lnum);
    System.out.println(intlnum);
    double tot = intfnum / intlnum; 
    System.out.println(tot);
    total = Double.toString(tot);
    System.out.println(total);
    } else {
        total = null;
    }
    return total;
}

}
4

4 に答える 4

9

配列は、解析された方程式を表すための間違った構造です。演算子の優先順位を表すことができる構造が必要です。このタイプの問題を処理するための典型的なメカニズムは、抽象構文木です。10-10 / 5 + 3の例では、次のようなツリーを作成することをお勧めします。

 <result>
  /   \
 '-' '+'
 / \ / \
10 '/'  3
   / \
  10  5

優先順位の高い演算子を使用してツリーの下位にあるこのタイプの構造では、ボトムアップ評価を実行して正しい結果を得ることができます。

于 2012-09-16T16:19:45.297 に答える
4

あなたがしなければならないのは、プレフィックス入力をポストフィックス形式に変換することだけです。次に、スタックを使用して簡単に魔法をかけることができます。コマンドパターンを使用して、完全なソリューションを作成しました。

中置を後置に変換する方法

    public static List<String> infixToPostfixConvert(String input) {

    int priority = 0;
    String postfixBuffer = "";
    Stack<Character> stack = new Stack<Character>();
    List<String> postfixArray = new ArrayList<String>();

    for (int i = 0; i < input.length(); i++) {
        char ch = input.charAt(i);
        if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {

            if (postfixBuffer.length() > 0) {
                postfixArray.add(postfixBuffer);
            }
            postfixBuffer = "";
            // check the precedence
            if (stack.size() <= 0)
                stack.push(ch);
            else {
                Character chTop = (Character) stack.peek();
                if (chTop == '*' || chTop == '/')
                    priority = 1;
                else
                    priority = 0;
                if (priority == 1) {
                    if (ch == '+' || ch == '-') {
                        postfixArray.add(String.valueOf(stack.pop()));
                        i--;
                    } else { // Same
                        postfixArray.add(String.valueOf(stack.pop()));
                        i--;
                    }
                } else {
                    if (ch == '+' || ch == '-') {
                        postfixArray.add(String.valueOf(stack.pop()));
                        stack.push(ch);
                    } else
                        stack.push(ch);
                }
            }
        } else {
            postfixBuffer += ch;
        }
    }
    postfixArray.add(postfixBuffer);
    int len = stack.size();
    for (int j = 0; j < len; j++)
        postfixArray.add(stack.pop().toString());

    return postfixArray;
}

次に、電卓インスタンスを使用して接尾辞文字列を渡す別のメソッドがあります。

    public void calculate(Calculator cal, List<String> postFix) {

    Stack<BigDecimal> stack = new Stack<BigDecimal>();

    for ( int i = 0; i < postFix.size(); i++ ) {

        String next = postFix.get(i);

        if (next.equals("+") || next.equals("-") || next.equals("*")
                || next.equals("/")) {
            ArithmaticCalculatorCommand cmd = new ArithmaticCalculatorCommand(
                    next.charAt(0), stack.pop(), stack.pop(), cal);
            Invoker invoker = new Invoker();
            invoker.compute(cmd);
            stack.push(cal.getCurrent());
        } else if ( false ){

        }
        else
        {
            stack.push(new BigDecimal(next.trim()));
        }
    }
}

完全な実装

コマンドインターフェイス

package org.sanjaya;
public interface Command {

    public void calculate();
}

コマンドの実装

package org.sanjaya.impl;

import java.math.BigDecimal;

import org.sanjaya.Command;

public class ArithmaticCalculatorCommand implements Command {

    private char operator;
    private BigDecimal leftOperand;
    private BigDecimal rightOperand;
    private Calculator calculator;

    public ArithmaticCalculatorCommand( char operator, BigDecimal leftOperand, BigDecimal rightOperand, Calculator calculator ) {
        this.leftOperand = leftOperand;
        this.rightOperand = rightOperand;
        this.operator = operator;
        this.calculator = calculator;
    }

    /*
     * This method invoke the three argument operation method that is only used for arithmetic calculations.
     * @param operator
     * @param leftOperand
     * @param rightOperand   * 
     * @see org.sanjaya.Command#calculate()
     */
    public void calculate() {
        calculator.operation( operator, leftOperand, rightOperand );        
    }   
}

電卓クラス(受信者)

package org.sanjaya.impl;

import java.math.BigDecimal;

public class Calculator {

    private static Calculator calculator;   
    private BigDecimal current = new BigDecimal( 0 );

    private Calculator()
    {

    }

    public static Calculator getInstance()
    {
        if ( calculator == null )
        {
            calculator = new Calculator();
        }
        return calculator;
    }

    /*
     * This method calculate current value for any number of calculation operations.
     * Currently following operations are supported
     * +,-,*,/
     * 
     * @param operator
     * @param leftOperand
     * @param rightOperand
     *  
     */
    public void operation( char operator, BigDecimal leftOperand, BigDecimal rightOperand )
    {       
        switch ( operator )
        {
        case '+':
            current = leftOperand.add( rightOperand );
            break;
        case '-':
            current = rightOperand.subtract( leftOperand );
            break;
        case '/':
            current = rightOperand.divide(leftOperand);
            break;
        case '*':
            current = leftOperand.multiply( rightOperand );
            break;
        default:
            break;
        }       
    }

    public BigDecimal getCurrent() {
        return current;
    }

    public void setCurrent(BigDecimal current) {
        this.current = current;
    }

}

発動者クラス

package org.sanjaya.impl;

import java.math.BigDecimal;

import org.sanjaya.Command;
public class Invoker {

    public void compute( Command command )
    {
        command.calculate();
    }   
}

クライアントクラス

package org.sanjaya.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
import java.util.logging.Logger;
public class CalculatorParser {

    public static Logger logger = Logger.getLogger( "Calculator_Logger" );

    public static void main( String a [] )
    {
        new CalculatorParser().start();
    }

    /*
     * This is the starting point of the program. It receives input from the command line 
     * and process them further and sends to calculate function. At the end this method 
     * displays the calculated result.
     */
    public void start()
    {
        Scanner scanner = new Scanner( System.in );
        logger.info("\n\t Please input expression to calculate::");

        String line = scanner.nextLine();
        List<String> postfixString = CalculatorParser.infixToPostfixConvert( line );
        Calculator calculator = Calculator.getInstance();
        calculator.setCurrent( new BigDecimal( 0 ) );

        calculate( calculator, postfixString );

        logger.info("Result is " + calculator.getCurrent() );
    }

    /*
     * This method keeps a stack to process postfix version of the input and execute the right command implementation.
     * Currently this method supports for arithmetic command calculations only.
     * @param Cal
     * @param postFix
     */
    public void calculate(Calculator cal, List<String> postFix) {

        Stack<BigDecimal> stack = new Stack<BigDecimal>();

        for ( int i = 0; i < postFix.size(); i++ ) {

            String next = postFix.get(i);

            if (next.equals("+") || next.equals("-") || next.equals("*")
                    || next.equals("/")) {
                ArithmaticCalculatorCommand cmd = new ArithmaticCalculatorCommand(
                        next.charAt(0), stack.pop(), stack.pop(), cal);
                Invoker invoker = new Invoker();
                invoker.compute(cmd);
                stack.push(cal.getCurrent());
            } else if ( false ){

            }
            else
            {
                stack.push(new BigDecimal(next.trim()));
            }
        }
    }

    /*
     * This method convert the infix into postfix in order to proceed in the calculation.
     * @param input 
     */
    public static List<String> infixToPostfixConvert(String input) {

        int priority = 0;
        String postfixBuffer = "";
        Stack<Character> stack = new Stack<Character>();
        List<String> postfixArray = new ArrayList<String>();

        for (int i = 0; i < input.length(); i++) {
            char ch = input.charAt(i);
            if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {

                if (postfixBuffer.length() > 0) {
                    postfixArray.add(postfixBuffer);
                }
                postfixBuffer = "";
                // check the precedence
                if (stack.size() <= 0)
                    stack.push(ch);
                else {
                    Character chTop = (Character) stack.peek();
                    if (chTop == '*' || chTop == '/')
                        priority = 1;
                    else
                        priority = 0;
                    if (priority == 1) {
                        if (ch == '+' || ch == '-') {
                            postfixArray.add(String.valueOf(stack.pop()));
                            i--;
                        } else { // Same
                            postfixArray.add(String.valueOf(stack.pop()));
                            i--;
                        }
                    } else {
                        if (ch == '+' || ch == '-') {
                            postfixArray.add(String.valueOf(stack.pop()));
                            stack.push(ch);
                        } else
                            stack.push(ch);
                    }
                }
            } else {
                postfixBuffer += ch;
            }
        }
        postfixArray.add(postfixBuffer);
        int len = stack.size();
        for (int j = 0; j < len; j++)
            postfixArray.add(stack.pop().toString());

        return postfixArray;
    }
}
于 2013-05-10T11:29:12.177 に答える
0

私はドットを機能させませんでした、それは別の日です。

mainまたはでlaunch、ボタンにテキストをbuttonHandlerに送信させます。

buttons.get(i).setOnAction(ev -> buttonHandler(text))

メソッドで:

  • そのテキストが数字の場合は、それを追加するだけです。
  • オペレーターの場合は、スタックに追加します。
  • スタックに*または/があった場合は、計算を実行し、新しい番号をスタックに追加します。
  • 最後に、スタックには+と-しかありません
  • 結果を計算します。

コード:

private void buttonHandler(String buttonValue) {
    String newInput = tfInput.getText();

    switch (buttonValue) {
        default:
            // If a previous calculation was made, reset input.
            if (lastOperator.equals("=")) {
                lInput.setText("");
                tfInput.setText(buttonValue);

            // else append the new input.
            } else {
                tfInput.appendText(buttonValue);
            }
            break;
        case " ":
            break;
        case ".":
            if(!input.contains(".")) {
                tfInput.appendText(buttonValue);
            }
            break;
        case "DEL":
            try {
                tfInput.setText("" + newInput.substring(0, tfInput.getText().length() - 1));
            } catch (Exception ex) { }
            break;

        // Operators
        case "x":
        case "/":
        case "+":
        case "-":
        case "=":

            if (newInput.length() > 0) {
                lInput.setText(lInput.getText() + newInput + " " + buttonValue + " ");

                try {
                    // If the previous operator has priority, make a calculation and push to stack
                    if (!input.empty()) {
                        if (input.peek().equals("x")) {
                            input.pop();
                            newInput = new BigDecimal(input.pop()).multiply(new BigDecimal(newInput)).toString();
                        } else if (input.peek().equals("/")) {
                            input.pop();
                            newInput = new BigDecimal(input.pop()).divide(new BigDecimal(newInput), 3, RoundingMode.HALF_UP).stripTrailingZeros().toString();
                            System.out.println(newInput);
                        }
                    }
                } catch (Exception ex) {
                    System.out.println("something is this part went wrong");
                }

                // If the "=" wasn't pressed, add input to the stack and set the textfield empty.
                if (!buttonValue.equals("=")) {
                    // Push to stack and empty input.
                    input.push(newInput);
                    input.push(buttonValue);
                    tfInput.setText("");

                // The button is "=". Prepare for final calculation
                } else {
                    if(!input.empty()) {
                        try {
                            // Reverse items.
                            Stack<String> stack = new Stack<>();
                            stack.push(newInput);
                            while (!input.empty()) {
                                stack.push(input.pop());
                            }

                            // Perform final calculation.
                            while (!stack.empty()) {
                                String firstNumber = stack.pop();
                                if (stack.peek().equals("+")) {
                                    stack.pop();
                                    newInput = new BigDecimal(firstNumber).add(new BigDecimal(stack.pop())).toString();
                                } else if (stack.peek().equals("-")) {
                                    stack.pop();
                                    newInput = new BigDecimal(firstNumber).subtract(new BigDecimal(stack.pop())).toString();
                                }
                                if (!stack.empty()) {
                                    stack.push(newInput);
                                } else {
                                    tfInput.setText(newInput);
                                }
                            }

                        } catch (Exception ex) {
                            System.out.println("something in the second part went wrong");
                        }
                    } else {
                        tfInput.setText(newInput);
                    }
                }
            }
    }
    lastOperator = buttonValue;
}

文字列を計算する場合は、次のようなものを「起動」方法に入れます。

 String test = "10-10/5+3=";
    for (int i = 0; i < test.length(); i++) {
        buttonHandler(test.charAt(i) + "");
    }
于 2018-03-22T22:29:28.370 に答える
0
// this calculator class can calculate numbers with multiple operators

package com.jhunrel25.calculator;

import java.math.*;
import java.util.*;

class Calculator {
    private static String stringParameter;

    Calculator(String calculateStringParameter) {
    stringParameter =
        calculateStringParameter.
        replaceAll("(?<=[\\d])(?=[*/+-])", " ").
        replaceAll("(?<=[*/+-])(?=[\\d])", " ");
}
public static String results() {

    Scanner scanner = new Scanner(stringParameter);

    LinkedList<String> data = new LinkedList<String>();
    while (scanner.hasNext()) {
        data.add(scanner.next());
    }
    do {

        // multiplication
        if (data.get(1).equals("*")) {

            BigDecimal x = new BigDecimal(data.get(0));
            BigDecimal y = new BigDecimal(data.get(2));

            data.set(0, (x.multiply(y).toString()));
            data.remove(1);
            data.remove(1);


            // division
        } else if (data.get(1).equals("/")) {

            BigDecimal x = new BigDecimal(data.get(0));
            BigDecimal y = new BigDecimal(data.get(2));

            if (Double.parseDouble(data.get(0)) < 1 || Double.parseDouble(data.get(2)) < 1) {
                return "Divided by 0 Situation.";

            } else if (Double.parseDouble(data.get(0)) < Double.parseDouble(data.get(2))) {
                return "Dividend must be larger than Divisor.";

            } else {

                data.set(0, (x.divide(y).toString()));
                data.remove(1);
                data.remove(1);
            }

            // addition
        } else if (data.get(1).equals("+")) {

            BigDecimal x = new BigDecimal(data.get(0));
            BigDecimal y = new BigDecimal(data.get(2));

            data.set(0, (x.add(y).toString()));
            data.remove(1);
            data.remove(1);


            // subtraction
        } else if (data.get(1).equals("-")) {

            BigDecimal x = new BigDecimal(data.get(0));
            BigDecimal y = new BigDecimal(data.get(2));

            data.set(0, (x.subtract(y).toString()));
            data.remove(1);
            data.remove(1);
        }

    } while (data.size() != 1);
    return data.get(0);
}

}

于 2021-12-27T22:40:25.747 に答える