PolyChordTetra PolyChordTetra - 3 months ago 16
Java Question

Calculator which accept two integers and operand

I'm suppose to write a program which asks the user to enter 2 integers and a token(operator) in ANY order.

After that, the data is suppose to go to a switch statement which performs the arithmetic between the inputted integers.
I need a hint on how to approach this with hasNext() and hasNextInt().

I tried writing a nested if..else with hasNext() to find the 3 tokens and then the 2 integers but the data doesn't seem to reach the switch statement.

Scanner scan = new Scanner(System.in);
int operand1 = scan.nextInt();
int operand2 = scan.nextInt();
char operator = scan.nextLine().charAt(0);

if(hasNext()) { //Doesn't this take in any token?

if(hasNext()) {

if(hasNext()) {

switch(operator){

case '+': int addition = operand1 + operand2;
System.out.println(addition);

break;

case '-': int subtraction = operand1 - operand2;
System.out.println(subtraction);

break;

case '*': int multiplication = operand1 * operand2;
System.out.println(multiplication);

break;

case '/': int division = operand1/ operand2;
System.out.println(division);

case '%': int modulus = operand1 % operand2;
System.out.println(modulus);

break;

case '^': int exponentiation = operand1 ^ operand2;
System.out.println(exponentiation);

break; }}}}

alt alt
Answer

Since this is an assignment, it would be wrong to just give you code but let's walk through it. Most assignments like this can have well defined steps 'Input' -> 'Processing' -> 'Output'

Input

Option 1

Use hasNext() / hasNextInt(). First declare the variables at the lowest possible scope (this would be immediately outside the ifs):

int int1;
int int2;
char op;

There are really three options for the input

  1. int int char
  2. int char int
  3. char int int

so you would need nested ifs to determine which case.

Scanner scan = new Scanner(System.in);
if (scan.hasNextInt()) {
    // Consume int1 or the following if will always be true!
    if (scan.hasNextInt()) {
        // Inside case 1
    } else {
        // Inside case 2
    }
} else {
    // Inside case 3
}

The problem is knowing when to store the nextInt() into int1 or int2. This can be solved in two ways

  • have an extra boolean indicating whether int1 was found yet

    boolean storedInt1 = false;
    // ...
    if (!storedInt1) {
        int1 = scan.nextInt();
        storedInt1 = true;
    } else {
        int2 = scan.nextInt();
    }
    
  • use Integer (auto-boxing/unboxing will handle the int<->Integer conversions for you)

    Integer int1 = null;
    Integer int2 = null;
    // ...
    if (int1 == null) {
        int1 = scan.nextInt();
    } else {
        int2 = scan.nextInt();
    }
    

Option 2

Use regexes. Regular expressions are your friends once you get to know them and Java has nice support.

There are many ways to accomplish the same thing but here's one way:

// First get all input at once
Scanner scan = new Scanner(System.in);
String input = scan.nextLine();

You can use multiple regexes to find (not match) the input

Matcher twoInts = Pattern.compile("(\\d+)\\D*(\\d+)").matcher(input);
if (twoInts.find()) {
    int1 = Integer.parseInt(twoInts.group(1));
    int2 = Integer.parseInt(twoInts.group(2));
} // else uh oh?

Matcher anyNonDigit = Pattern.compile("([^\\d\\s]+)").matcher(input);
if (anyNonDigit.find()) {
    op = anyNonDigit.group(1).charAt(0);
} // else uh oh?

Note that these regexes won't work for negative numbers as is.

Regexes explained:

  • "(\\d+)\\D*(\\d+)"
    • "(\\d+)" matches and captures any digit "\\d" one or more times "+"
    • "\\D*" matches any non-digit "\\D" any number of times "*"
  • "([^\\d\\s]+)"
    • "[\\d\\s]" matches any digit "\\d" or whitespace "\\s"
      • "[^ ... ]" matches the inverse i.e. this matches any character that is not a digit AND not a whitespace
    • one or more times "+"
    • and capture it "( ... )"

Processing & Output

Leave as you have already but the switch would be at the same level as the ifs used for input. It may be a good idea for some error checking here too.

Integer int1 = null;
// ...

// All the input ...

// Check for errors, e.g.
if (int1 == null || int2 == null || op == 0) {
    // Input failed, print some message and exit
}

switch (op) {
    // Any possible operators

default:
    // Operator unknown, print some message and exit
    break;
}
Comments