user1879242
user1879242

Reputation: 13

Mathematical expression when using arrays (Java)

The problem is the following: I need to make an Java program that gives you random numbers (e.g. 1 2 3) and after that it needs to give random operators (e.g. + *).

Well, I have got that part, but how do I check that answer with Java code. The answer should be 7.

The following code is the problem:

    String operations[] = {"+ ","- ","* ","/ "};
    System.out.println("How many digits?");
    int times = scan.nextInt();
    this.times = times;
    this.operation = new String[times-1];
    this.digits = new int[times];

    for (int i = 0; i < times - 1; i++)
    {
        operation[i] = operations[rand.nextInt(4)];
        System.out.print(operation[i]);
    }

    for(int i = 0; i < operation.length; i++)
    {
        System.out.print(digits[i]+" ");
        System.out.println(digits[i] + operation[i] + digits[i]);         //first digit + - * / the first digit
    }

Hopefully these snippets are a bit clear. What I want to do is to get random digits and operators. After that I want to run the expression.

Hope you can help me.

Upvotes: 0

Views: 3256

Answers (4)

Dawood ibn Kareem
Dawood ibn Kareem

Reputation: 79838

Here is an answer that allows multiple operands and respects order of operations, unlike any of the others that are currently here.

import java.util.Arrays;
import java.util.List;

public class Expression {
    private List<Integer> operands;
    private List<Character> operators;

    public Expression(List<Integer> operands, List<Character> operators) {
        this.operands = operands;
        this.operators = operators;
    }

    public Expression subExpression(int fromIndex, int toIndex) {
        return new Expression(
                operands.subList(fromIndex, toIndex), 
                operators.subList(fromIndex, toIndex - 1));
    }

    private int rightMost(char operator) {
        return operators.lastIndexOf(operator);
    }

    public double evaluate() {
        if (operands.size() == 1) {
            return operands.get(0).doubleValue();
        }

        if (rightMost('+') > -1){
            return subExpression(0, rightMost('+') + 1).evaluate()
                + subExpression(rightMost('+') + 1, operands.size()).evaluate();  
        }
        if (rightMost('-') > -1){
            return subExpression(0, rightMost('-') + 1).evaluate() 
                - subExpression(rightMost('-') + 1, operands.size()).evaluate();  
        }
        if (rightMost('*') > -1){
            return subExpression(0, rightMost('*') + 1).evaluate() 
                * subExpression(rightMost('*') + 1, operands.size()).evaluate();  
        }
        if (rightMost('/') > -1){
            return subExpression(0, rightMost('/') + 1).evaluate() 
                / subExpression(rightMost('/') + 1, operands.size()).evaluate();  
        }
        return 0;
    }

    @Override
    public String toString() {
        StringBuilder toReturn = new StringBuilder();
        for (int index = 0; index < operands.size(); index++){
        toReturn.append(operands.get(index));
        toReturn.append(" ");
        toReturn.append(
                index == operators.size() ? "=" : operators.get(index));
        toReturn.append(" ");
       }
       toReturn.append(evaluate());
       return toReturn.toString();
    }

    public static Expression makeRandom(
        int minimum, int maximum, int numberOfOperands) {
        Integer[] operands = new Integer[numberOfOperands];
        Character[] operators = new Character[numberOfOperands - 1];
        for (int index = 0; index < numberOfOperands; index++) {
            operands[index] = minimum 
                        + (int)(Math.random() * (maximum - minimum + 1));
        }
        for (int index = 0; index < numberOfOperands - 1; index++) {
            operators[index] = "+-*/".charAt((int)(Math.random() * 4));
        }
        return new Expression(Arrays.asList(operands), Arrays.asList(operators));
    }

    public static void main (String[] args){
        System.out.println(makeRandom(1, 10, 6));
        System.out.println(new Expression(
                Arrays.asList(1, 2, 3), Arrays.asList('+', '*')));
    }
}

The main is just here for a quick and dirty test. Here is the output from one run of it. As you can see, 1 + 2 * 3 gives the correct answer - no other answer that is currently on this page gets this right.

10 / 5 / 6 * 9 + 9 * 1 = 12.0
1 + 2 * 3 = 7.0

I've made evaluate return double to avoid any nasty surprises with integer division. This could easily be changed if necessary. Also, there's no error handling here - there are a few methods that should do some error handling on their parameters, and something really should be done about capturing division by zero.

This works by splitting an expression into smaller subexpressions, evaluating each recursively, then bringing them back together. The magic is in the order of the operations in the evaluate method. The different operators have to be treated in this order, for these reasons.

  • + has to be considered before -, so that a - b + c parses as (a - b) + c, not a - (b + c).
  • * has to be considered before /, so that a / b * c parses as (a / b) * c, not a / (b * c).
  • + and - both have to be considered before * and /, so that * and / are evaluated first.
  • Subtraction has to work from right to left, so that a - b - c parses as (a - b) - c, not a - (b - c).
  • Division has to work from right to left, so that a / b / c parses as (a / b) / c, not a / (b / c).
  • Addition and multiplication could be done from left to right or from right to left, but having written the rightMost method, it made sense to do them from right to left.

Upvotes: 1

Jhanvi
Jhanvi

Reputation: 5139

You can try something like this:

    String operations[] = {"+", "-", "*", "/"};
    int idx = new Random().nextInt(operations.length);
    String random_operator = "/";
    int int_1 = (int) (Math.random() * 100);
    int int_2 = (int) (Math.random() * 100);

    Scanner s = new Scanner(System.in);
    int result = 0;
    if (random_operator.equals("*")) {
        result = int_1 * int_2;
        System.out.println(int_1 + random_operator + int_2);
    } else if (random_operator.equals("+")) {
        result = int_1 + int_2;

        System.out.println(int_1 + random_operator + int_2);
    } else if (random_operator.equals("-")) {
        if (int_1 < int_2) {
            result = int_2 - int_1;
            System.out.println(int_2 + random_operator + int_1);
        } else {
            System.out.println(int_1 + random_operator + int_2);
            result = int_1 - int_2;
        }


    } else if (random_operator.equals("/")) {
        if (int_1 < int_2) {

            result = int_2 / int_1;
            System.out.println(int_2 + random_operator + int_1);
        } else {
            result = int_1 / int_2;
            System.out.println(int_1 + random_operator + int_2);
        }


    }

    if (s.nextInt() == result) {
        System.out.println("Correct answer");
    } else {
        System.out.println("Wrong answer");
    }

Please note that i have considered only integers in above example.

Upvotes: 0

Paul Samsotha
Paul Samsotha

Reputation: 209004

You can use a switch statement and do something like this:

switch(operations[i]) {
    case "+": number1 + number2; break;
    case "-": number1 - number2; break;
    case "*": number1 * number2; break;
    case "/": number1 / number2; break;
}

Upvotes: 0

Ankit Rustagi
Ankit Rustagi

Reputation: 5637

This would check if the equation you generated results in 7 or not

int result = digits[0];
int i=0;

for(i=0;i<times-1;i++)
{
    String operation = operations[i];

    if(operation.equals("+") result += digits[i+1];    
    else if(operation.equals("-") result -= digits[i+1];    
    else if(operation.equals("*") result *= digits[i+1];    
    else if(operation.equals("/") result /= digits[i+1];    
}
if(result==7) System.out.println("You got the correct answer ie 7");
else System.out.println("You got "+result);

EDIT: just corrected a typo.

Upvotes: 0

Related Questions