Safe Calculator (Exception Handling)

easy Exception Handling

Problem

Each input line has the form a op b with the operators + - * /. Print the result of every line. Division is integer division (cut toward zero). Print Error: division by zero if b is 0, Error: unknown operator for any other operator, and Error: bad input if a or b is not an integer or a part is missing. The program must not stop after an error.

Constraints

  • 1 <= lines <= 1000

Examples

Input

6 / 3
5 / 0
2 + 3

Output

2
Error: division by zero
5

Solutions

Best approachTime O(lines)Space O(lines)

A try block runs the risky code. Each catch block handles one kind of problem. The loop continues after an error, so one bad line does not stop the whole program.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process commands line by line.
 * Input   : Several lines of commands.
 * Output  : One line for each input line.
 * Approach: Catch the exceptions.
 * Time    : O(lines)
 * Space   : O(lines)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(String[] lines) {
        String[] output = new String[lines.length];

        for (int i = 0; i < lines.length; i++) {
            String[] parts = lines[i].split("\\s+");

            // Step 1: Try to do the work. Any problem becomes an exception.
            try {
                // Step 2: Integer.parseInt throws NumberFormatException for bad text. A missing part throws ArrayIndexOutOfBoundsException.
                long a = Long.parseLong(parts[0]);
                String operator = parts[1];
                long b = Long.parseLong(parts[2]);

                switch (operator) {
                    case "+":
                        output[i] = String.valueOf(a + b);
                        break;
                    case "-":
                        output[i] = String.valueOf(a - b);
                        break;
                    case "*":
                        output[i] = String.valueOf(a * b);
                        break;
                    case "/":
                        // Step 3: Dividing by zero throws ArithmeticException. Java long division cuts toward zero.
                        output[i] = String.valueOf(a / b);
                        break;
                    default:
                        output[i] = "Error: unknown operator";
                }
            } catch (ArithmeticException error) {
                output[i] = "Error: division by zero";
            } catch (NumberFormatException | ArrayIndexOutOfBoundsException error) {
                // Step 4: Handle several exception types in one catch block.
                output[i] = "Error: bad input";
            }
        }
        return output;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        java.util.List<String> all = new java.util.ArrayList<>();
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine().trim();
            if (!line.isEmpty()) {
                all.add(line);
            }
        }
        String[] lines = all.toArray(new String[0]);
        System.out.println(String.join("\n", solve(lines)));
    }
}
Hints (2)
  1. Which exception does Java throw for 5 / 0 with integers?
  2. What happens to the loop after a catch?