到目前为止我有以下工作正常。我确定可能有一种更简单的方法可以做到这一点,但我需要改变/改变的是Matheq的顶级方法。 Math方法执行单个数学运算。
它适用于带有+, - ,*和/.
的任何单个操作我的问题是解决一个更大的等式,如10 - 10/5 + 3。 然而,它确实正确地解决了10/5 + 65 * 2。 原因是每个部分,数字和操作都被拆分为字符串数组。每次操作完成后,数字和操作将替换为该等式的结果。可能看起来更令人困惑,但我想不出更好的方法。它无法解决其他方程的原因是因为我将字符串映射回字符串数组。
字符串数组的示例 防爆。 10 - 10/5 + 3 String = {10, - ,10,/,5,+,3} 在操作之后先进行除法,然后从左到右减去然后加法 String = {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;
}
}
答案 0 :(得分:9)
数组是表示解析方程的错误结构。您需要具有可以表示运算符优先级的结构。处理此类问题的典型机制是abstract syntax tree。对于10 - 10/5 + 3示例,您可能希望构建一个如下所示的树:
<result>
/ \
'-' '+'
/ \ / \
10 '/' 3
/ \
10 5
这种具有高优先级操作符的结构会降低树的结构,然后您可以执行自下而上的评估以获得正确的结果。
答案 1 :(得分: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;
}
然后我有另一个使用Calculator实例并传递后缀字符串的方法。
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;
}
}
答案 2 :(得分: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;
}
如果你想在&#39;发布&#39;中计算一个像这样的字符串。 mehtod:
String test = "10-10/5+3=";
for (int i = 0; i < test.length(); i++) {
buttonHandler(test.charAt(i) + "");
}