0

I am currently a early CS student and have begun to start projects outside of class just to gain more experience. I thought I would try and design a calculator.

However, instead of using prompts like "Input a number" etc. I wanted to design one that would take an input of for example "1+2+3" and then output the answer.

I have made some progress, but I am stuck on how to make the calculator more flexible.

Scanner userInput = new Scanner(System.in);
String tempString = userInput.nextLine();
String calcString[] = tempString.split("");

Here, I take the user's input, 1+2+3 as a String that is then stored in tempString. I then split it and put it into the calcString array.

This works out fine, I get "1+2+3" when printing out all elements of calcString[].

for (i = 0; i <= calcString.length; i += 2) {
    calcIntegers[i] = Integer.parseInt(calcString[i]);
}

I then convert the integer parts of calcString[] to actual integers by putting them into a integer array.

This gives me "1 0 2 0 3", where the zeroes are where the operators should eventually be.

if (calcString[1].equals("+") && calcString[3].equals("+")) {
    int retVal = calcIntegers[0] + calcIntegers[2] + calcIntegers[4];
    System.out.print(retVal);
}

This is where I am kind of stuck. This works out fine, but obviously isn't very flexible, as it doesn't account for multiple operators at the same like 1 / 2 * 3 - 4.

Furthermore, I'm not sure how to expand the calculator to take in longer lines. I have noticed a pattern where the even elements will contain numbers, and then odd elements contain the operators. However, I'm not sure how to implement this so that it will convert all even elements to their integer counterparts, and all the odd elements to their actual operators, then combine the two.

Hopefully you guys can throw me some tips or hints to help me with this! Thanks for your time, sorry for the somewhat long question.

Guy
  • 46,488
  • 10
  • 44
  • 88
JyCan12
  • 43
  • 5
  • Since you just started, try to start low with single input and keep expanding untill you learn `regex` – bananas Mar 09 '17 at 05:37
  • Either implement an [interpreter](https://en.wikipedia.org/wiki/Interpreter_pattern), or cheat. Use `ScriptEngine`. Scanner sc = new Scanner(System.in); ScriptEngine se = new ScriptEngineManager().getEngineByName("js"); try { System.out.println(se.eval(sc.nextLine())); } catch (ScriptException e) { e.printStackTrace(); } – Elliott Frisch Mar 09 '17 at 05:39
  • See http://stackoverflow.com/a/26227947/18157 – Jim Garrison Mar 09 '17 at 05:41
  • 1
    The "real" CS approach would be: create a PARSER that dissects your input string into a TREE where nodes represent operators and leaves represents operands. As of now, your approach of using that array will make any reasonable enhancements very hard to code, just because your code needs to deal with such low level abstractions. – GhostCat Mar 09 '17 at 05:50

3 Answers3

1

Create the string to hold the expression :

String expr = "1 + 2 / 3 * 4"; //or something else

Use the String method .split() :

String tokens = expr.split(" ");

for loop through the tokens array and if you encounter a number add it to a stack. If you encounter an operator AND there are two numbers on the stack, pop them off and operate on them and then push back to the stack. Keep looping until no more tokens are available. At the end, there will only be one number left on the stack and that is the answer.

The "stack" in java can be represented by an ArrayList and you can add() to push items onto the stack and then you can use list.get(list.size()-1); list.remove(list.size()-1) as the pop.

0

You are taking input from user and it can be 2 digit number too. so

for (i = 0; i <= calcString.length; i += 2) {
    calcIntegers[i] = Integer.parseInt(calcString[i]);
}

will not work for 2 digit number as your modification is i+=2. Better way to check for range of number for each char present in string. You can use condition based ASCII values.

c0der
  • 18,467
  • 6
  • 33
  • 65
0

Since you have separated your entire input into strings, what you should do is check where the operations appear in your calcString array.

You can use this regex to check if any particular String is an operation:

Pattern.matches("[+-[*/]]",operation )

where operation is a String value in calcString

Use this check to seperate values and operations, by first checking if any elements qualify this check. Then club together the values that do not qualify.

For example,

If user inputs

4*51/6-3

You should find that calcString[1],calcString[4] and calcString[6] are operations.

Then you should find the values you need to perform operations on by consolidating neighboring digits that are not separated by operations. In the above example, you must consolidate calcString[2] and calcString[3]

To consolidate such digits you can use a function like the following:

public int consolidate(int startPosition, int endPosition, ArrayList list)
{       
    int number = list.get(endPosition);
    int power = 10;
    for(int i=endPosition-1; i>=startPosition; i--)
    {
        number = number + (power*(list.get(i)));
        power*=10;
    }   
    return number;      
}

where startPosition is the position where you encounter the first digit in the list, or immediately following an operation,

and endPosition is the last position in the list till which you have not encountered another operation.

Your ArrayList containing user input must also be passed as an input here!

In the example above you can consolidate calcString[2] and calcString[3] by calling:

consolidate(2,3,calcString)

Remember to verify that only integers exist between the mentioned positions in calcString!

REMEMBER!

  1. You should account for a situation where the user enters multiple operations consecutively.
  2. You need a priority processing algorithm based on the BODMAS (Bracket of, Division, Multiplication, Addition and Subtraction) or other mathematical rule of your preference.
  3. Remember to specify that your program handles only +, -, * and /. And not power, root, etc. functions.
  4. Take care of the data structures you are using according to the range of inputs you are expecting. A Java int will handle values in the range of +/- 2,147,483,647!
maverick18
  • 11
  • 4