如何使Java中的字符串计算器与负数一起工作?

如何使Java中的字符串计算器与负数一起工作?,java,regex,numbers,calculator,Java,Regex,Numbers,Calculator,我目前正在用Java制作一个字符串计算器。现在,我正在尝试使它与负数一起工作(例如,当键入-3+7时,结果为4)。目前,当输入-3+7时,它将返回-4,因为它看到-是第一个运算符,所以它将对这些数字执行减法运算。在calcOperators列表中,我添加所有运算符,而在calcOperands中,我添加所有数字并将它们存储为整数。我的问题是,如何使程序接受-1或-2作为一个整数,而不是将-1作为运算符,2作为数字。我尝试使用numberformatexception,但不起作用。如果有人能帮助我

我目前正在用Java制作一个字符串计算器。现在,我正在尝试使它与负数一起工作(例如,当键入-3+7时,结果为4)。目前,当输入-3+7时,它将返回-4,因为它看到-是第一个运算符,所以它将对这些数字执行减法运算。在calcOperators列表中,我添加所有运算符,而在calcOperands中,我添加所有数字并将它们存储为整数。我的问题是,如何使程序接受-1或-2作为一个整数,而不是将-1作为运算符,2作为数字。我尝试使用numberformatexception,但不起作用。如果有人能帮助我,我将不胜感激

import java.util.ArrayList; //Importing the ArrayList module for creating arrays in the class
import java.util.regex.Pattern;

public class stringCalculator {

private String string; //Declaring the string 'string' as a field in order to be able to use it
private ArrayList<Integer> calcOperands; //The list that will hold the operands as Integers
private ArrayList<Character> calcOperators; //The list that will hold the operators as characters
private ArrayList<Character> priorityList; //This list holds characters, 1 for multiplication and division sign and 2 for addition and substraction respectively

private int result;//An integer variable, that will be the result from the expression

public stringCalculator(String string){ //A constructor
    this.string = string; //this. is used for updating the variable
    /**
     * Creating the two lists for holding the operands and operators
     */
    calcOperands = new ArrayList<Integer>();
    calcOperators = new ArrayList<Character>();


}

public boolean checkInput(){ //This method checks whether the input of the user contains integers and/or operators

    for(int i =0; i<string.length();i++){ //A for loop that will check each individual character from the expression
        if(!validCharacter(string.charAt(i)) && !parseInput(string.charAt(i))){// If one of the characters is not integer, white space or operator, return false
            return false;
            }
    }
    String[] items = string.split(" "); // Creating a new list items, that will store strings from the input
    System.out.println(string);
    //System.out.println(items[0]);
    for(int count2 = 0;count2<items.length;count2++){ //For loop for adding the operands in the items list

        if(!items[count2].equals("") || items[count2].contains("-")){ //If the element from the input is not an empty string, add it to the items list
            calcOperands.add(Integer.parseInt(items[count2]));
            System.out.println(items[count2]);
            System.out.println(calcOperands);
        }
        //else if(items[count2-1]=="-" &&){

        //}
    }
    return true; //Return true if all the elements in the input are either integers, white spaces or operators
}

private boolean validCharacter(char character){ //Checks the validity of every character in the user input
    if(Character.isWhitespace(character)){ //If there is a white space character, return true
        return true;
    }
    if(Character.isDigit(character)){ //If the character is a digit(integer), return true as well
        return true;
    }

    //String num = "-2";
    //if(string[0]=="-")){

    //}
    return false; //If there is a character in the input that is neither an integer nor a white space, return false
}
public boolean parseInput(char character){ //The parseInput method splits the input of the user and puts operands in calcOperands list and operators in calcOperators list

    if(character == '+' || character == '-' || character == '*' || character == '/'|| character == '=' ) { //If there is a character that is equal to one of the operators, add it to the calcOperators list
        calcOperators.add(character);
        System.out.println(calcOperators);
        System.out.println(character);
        string = string.substring(0, string.indexOf(character)) + " " + string.substring(string.indexOf(character)+1); //The new input now contains the operands, the operators are being removed

    return true; //Return true if the character is an operator
    }
    else if(character == '-' && Character.isDigit(character+1)){ //This is where I try to make the programme accept -1 as one number
        calcOperands.add(character+1);
        System.out.println(calcOperands);
        string = string.substring(0, string.indexOf(character+1)) + " " + string.substring(string.indexOf(character)+1);
    }

return false; //If the character is not an operator, return false 
}


public void calculatePriority(){ //This method is used to calculate the priority operators, i.e. do the multiplication and division before addition and substraction
    priorityList = new ArrayList<Character>(calcOperators); //Creating the priorityList which will store the characters 1 and 2. It has the same length as the calcOperators list and is the same as it initially

    char i = 0; //A counter variable, that will be used to inspect each element in the prirorityList
    for(char j : priorityList){ //A for loop for inspection each character in the priorityList
    if(j == '*' || j == '/'){ //If there is a multiplicaiton or division operator, replace it with 1 in the priorityList
        priorityList.set(i, (char)'1');
    }
    else if(j == '+' || j =='-'){ //If the operators are addition or substraction, replace them with 2 in the priorityList
        priorityList.set(i, (char)'2');
    }
    i++; //Increment the counter i every time in order to circulate through each element in the list
    }
}

public int calculateResult(){ //This method calculates the result from the user's input and returns the result as an integer
    /**
     * Calling each of the previous methods in this one, so I can just call calculateResult() in the main class. This makes the programme more robust
     */
    checkInput();
    calculatePriority();


    try{
    while(priorityList.contains('1')){ //If the priorityList contains '1' in it
    int k = priorityList.indexOf('1'); //A new integer variable k, that will be equivalent to the first position, at which '1' is found in priorityList 
        if(calcOperators.get(k) == '*' ){ //If the element at position k in calcOperators list is multiplication
            calcOperands.set(k, calcOperands.get(k) * calcOperands.get(k+1)); //Replace the operator sign with the product of the operands between the sign itself

            calcOperands.remove(k+1); //Remove the element after k in calcOperands in order to have just the product in the list
            calcOperators.remove(k); //From calcOperators, remove the "*" for the numbers, on which the operation is performed
            priorityList.remove(k); //In priorityList, remove all the 1s


            result = calcOperands.get(k); //The result variable is now equal to the product of the number
        }
        else if(priorityList.indexOf('1')>=0 && calcOperators.get(k) == '/' ){ //Perform the same operations for the division operation, as we did the multiplication
            calcOperands.set(k, calcOperands.get(k) / calcOperands.get(k+1));
            calcOperands.remove(k+1);
            calcOperators.remove(k);
            priorityList.remove(k);



            result = calcOperands.get(k);
        }
    }

    while(priorityList.contains('2')){ //A loop that circulates when the priorityList contains a '2' in it, that means either an addition or substraction operation
        int g = priorityList.indexOf('2'); //The integer variable g is equivalent to the first position, at which the character '2' is found in the priorityList
        if(calcOperators.get(g) == '+' ){ //If the element in calcOperators is the "+" sign
            calcOperands.set(g, calcOperands.get(g) + calcOperands.get(g+1)); //Replace the operator g with the sum of the numbers between the operator
            calcOperands.remove(g+1); //Remove the element g+1, which is the second number for the operation, in order just the sum of the two numbers to be left in the calcOperands list
            calcOperators.remove(g); //Remove the + operator in the calcOperators list
            priorityList.remove(g); // Remove the '2' character in priorityList

            result = calcOperands.get(g); //The result is now equal to the sum of the numbers

        }
        else if(calcOperators.get(g) == '-'){ //Perform the same operations for the substraction opeartion as we did on the addition. They are both at the same priority, so it does not matter which operation goes fist
            calcOperands.set(g, calcOperands.get(g) - calcOperands.get(g+1));
            calcOperands.remove(g+1);
            calcOperators.remove(g);
            priorityList.remove(g);

            result = calcOperands.get(g);


        }
    }
}
    catch(RuntimeException r){
        //int k = priorityList.indexOf('1');
        //if((((CharSequence) calcOperands).charAt(0))=='-'){
            //calcOperands.set(k, -calcOperands.get(k) * calcOperands.get(k+1));
        //}
    }


    return result; //Return the final result of the input as an integer

}
}
import java.util.ArrayList//导入ArrayList模块以在类中创建数组
导入java.util.regex.Pattern;
公共类字符串计算器{
private String;//将字符串“String”声明为字段以便能够使用它
private ArrayList calcOperands;//将操作数保存为整数的列表
private ArrayList calcOperators;//将运算符作为字符保存的列表
private ArrayList priorityList;//此列表包含字符,1表示乘法和除法符号,2表示加法和减法符号
private int result;//一个整数变量,它将是表达式的结果
公共字符串计算器(字符串){//A构造函数
this.string=string;//this.用于更新变量
/**
*创建用于保存操作数和运算符的两个列表
*/
calcOperands=新的ArrayList();
calcOperators=新的ArrayList();
}
public boolean checkInput(){//此方法检查用户的输入是否包含整数和/或运算符

对于(inti=0;i整个过程都取决于语言的设计。(看起来你甚至不知道自己在处理一种语言,但相信我,它是一种语言。)

您基本上有两种选择:

  • 在“-5”中,您可以看到-作为数字的一部分
  • 您将
    -
    视为一元运算符
  • 在这两种情况下,您都应该知道要查找什么。我将假设第二种场景,因为它允许您引入其他一元运算符。因此您的语言语法如下所示:

    number: ... // a sequence of digits
    unary_operator: '-'
    binary_operator: '-' | '+' | '*' | '/'
    term: number | '(' expr ')'
    unaryex: unary_operator term | term
    expr: unaryex | unaryex binary_operator expr
    
    现在,对“-”的解释将有所不同,这取决于您是寻找一元运算符还是二元_运算符。请注意,示例语法是以这样一种方式编写的,不可能出现混淆


    例如,开头的“-”只能是一元运算符,但数字或完整子表达式后面出现的“-”必须是二元运算符(后面必须跟着另一个表达式).

    简单修复和即时修复是,将ParseInput更改为accept Position并传递char Position。并在添加到calcOperators之前检查该位置

    public boolean parseInput(char character,int position){ //The parseInput method splits the input of the user and puts operands in calcOperands list and operators in calcOperators list
    
        if ((character == '+' || character == '-' || character == '*' || character == '/'|| character == '=' )) { //If there is a character that is equal to one of the operators, add it to the calcOperators list
            if (position !=0 ){
                calcOperators.add(character);
                System.out.println(calcOperators);
                System.out.println(character);
                string = string.substring(0, position) + " " + string.substring(position+1); //The new input now contains the operands, the operators are being removed
            }
            return true; //Return true if the character is an operator
        }
        return false; //If the character is not an operator, return false
    }
    

    它对两个给定的数字执行操作是的,但我要做的是,当我在数字前面有一个负号时,将其作为一个整体接受,而不是作为运算符和数字接受。
    (?)(\\d+)(+)-*(?)(\\d+)
    这可能是一个有用的正则表达式。您对我的语言的定义是什么意思?我使用的是java/@Philip而不是编程语言。一种语言是由一组有效的输入及其输出定义的。在您的情况下,您需要一种定义良好的语言,说明每个符号在何处以及如何表示形式语言定义的+1,尽管我觉得可能是这样稍微超出了OP最初的预期范围。@fgysin是的,也许。但是奥托,也许他重新设计了这个东西,并重新发明了递归下降解析,然后事情就会成功,他的程序会更短,更容易理解,他会感到自豪。