matt shaffer
matt shaffer

Reputation: 3

Building a basic calculator in Java and need to check validity of the math expression input by the user

I am building a basic calculator in Java and have a few requirements to meet for it. it takes a math expression input from the user example. 3 * 5 ^ 5 (must be separated by spaces). I'm having trouble figuring out how to pass the basic math expression input string math to the isNumber function and then in that function checking the first [0] spot of the string and every 4th spot (since spaces are still in there?) after for a double. I can do it if I turn math into a string array, but the requirements specifically said I cannot turn string math into an array until afterwards. I know if I can figure this out, then it shouldn't be hard to make an operator validation function and do the same for the spots of the input... here is my current progress on the program.

import java.util.Scanner;

/**
 *
 * @author 
 */
public class Calculator2 {
    static ArrayList<String> validOperators = new ArrayList<String>(){{
            add("^");
            add("*");
            add("/");
            add("+");
            add("-");
        }}; 
    
    public static void main(String[] args) {
        System.out.println("This is a text based calculator!");
        Scanner in = new Scanner(System.in);        
        boolean loop = true;
        while (loop) {
            System.out.println("Enter a math expression ot type quit to exit: ");
            String math = in.nextLine();
            if ("quit".equalsIgnoreCase(math)) {
                System.out.print("Quitting");
                break;
            }
            
             if (isOperator(math)){
                 if (isNumber(math)){
                   String[] splitExpression = math.split("\\s+");
                     if(isValidExpression(splitExpression)){
                         for (int i=0; i<splitExpression.length; i++){
                             System.out.println(splitExpression[i]);
                    } 
                    System.out.println("Number of tokens: " + splitExpression.length);
                 }
                 }else {
                     System.out.println("invalid expression!");
                 }
             }else{
                 System.out.println("please use valid operators");
             }
            
            
        }
    }
    
    public static boolean isNumber(String number){
        return 
    }
} ```

Upvotes: 0

Views: 396

Answers (1)

rzwitserloot
rzwitserloot

Reputation: 102902

Numbers can be variable length, there can be multiple spaces - your approach (which involves things like 'check the 4th character') cannot work - you cannot work in absolute positions like this. It must be relative.

The usual approach is to realize that you've constructed an actual grammar here, and it can get quite complicated (toss in the ability to write parentheses and it's quite complicated indeed). Seems simple, but it just isn't.

Generally, you FIRST tokenize, which turns your stream of characters, into a stream of nodes. + is a node. So is 1.21398123. Nodes know what kind of thing they represent.

Then, you turn the stream of nodes into a tree. Then you calculate the result by going through the tree, from the leaves all the way up to the root.

i,e, this:

"10 * (2+3)"

is first turned into:

List.of(
  NumericNode.of(10), 
  Operator.MULTIPLY,
  Operator.OPEN_PAREN,
  NumericNode.of(2),
  Operator.ADD,
  NumericNode.of(3),
  Operator.CLOSE_PAREN);

Then that is turned into:

             *
           /   \
          10   +
              / \
              2  3

And that you can then trivially 'resolve' into 50 by collapsing nodes recursively.

As you can probably tell once you break it down like this: Not trivial.

You can search the web for tokenizers and parser tech on how to do this job. It'll take some reading.

Upvotes: 1

Related Questions