tags:

views:

127

answers:

5

Hello,

I'm writing a java method that takes a string of plus and minus operations, eg

"+1+2+3-5" and I want it to return an int of the answer.

I'm trying to do this as efficiently as possible. I've tried the String.split() method, but it gets slightly confusing with the pluses and minuses.

Can anyone help? No, this isn't homework.

A: 

Have a look at "RPN Calculator" for a good starting point.

GrayWizardx
The OP doesn't seem to be using RPN here
Pascal Thivent
No they arent, but RPN will work and be a straightforward starting point.
GrayWizardx
RPN is IMO not a good starting point. For a start, the OP's question does not require conversion from infix to postfix.
Stephen C
A: 

You are going to need to parse the string character by character. Something like

int foo(String s){  
    int total = 0;
    String currentNum = ""  
    for(int i =0;i<s.length;i++){   
        if(s[i] =="+"){   
           total += Integer.parseInt(currentNum);   
           currentNum = ""   
        }else if(s[i] =="-"){  
           total -= Integer.parseInt(currentNum);  
           currentNum = ""  
        }else{   
           currentNum += s[i]   
        }   
     }     
     return total;
}
RHicke
I was thinking of something like this. I only just realized why I didn't just do it. I was originally going to return it as an array of integers, and was worried about array length. Thanks!
Philip
@Philip: It's worth reconsidering your original plan - but using an `ArrayList<Integer>` instead - that way you don't need to worry about the length. Note that this answer won't actually compile for various reasons, and is also needlessly inefficient in terms of string manipulation.
Jon Skeet
(It also ignores the last number, by the way... because it only parses anything when it runs into + or - which it won't at the end.)
Jon Skeet
If you are going to parse other strings to evaluate you'll probably want to build a distinct parsing engine so that you can separate out you parsing code from the code that evaluates your tokens. If this is the only spot it's probably fine from a Software Engineering perspective to do it in the same spot.
RHicke
by the way treat this function as psuedocode I wrote it in 90 seconds
RHicke
+3  A: 

Well, a few things to think about...

  • You could potentially use split to help with the parsing, but you'll need the separators as well the numbers
  • You could scan through the string, remembering where the start of the current number is and then parsing it when you've found the end.
  • What data structures are you going to use to store the string after you parse it?
    • You may want to consider that subtracting 20 is like adding -20...
    • ... or you may want to think about alternating between number and operator, starting with an implicit "+" if the first character isn't "-"
  • You should strongly consider splitting the task up into the "parsing" and "evaluating" phases. In particular, you should be able to write tests for the evaluation phase even without writing any parsing code - and vice versa.
  • You say you want to do this as efficiently as possible - why? Efficiency is often (but certainly not always) the enemy of clarity. I would at least try to go for a clear solution first and then work out how efficient it is. Often a clear solution will be "efficient enough".
Jon Skeet
+2  A: 

The shunting yard algorithm is what you need here and it should be pretty easy to implement it in Java.

Pascal Thivent
Yes ... but the OP's requirements are to support '+' and '-'; no operator precedence and no parentheses are required. So shunting yard is unnecessarily complicated. (Of course if he/she changes the requirements ...)
Stephen C
+1  A: 

Generally with these types of problems, you need a binary tree. However, your case is simpler, and you can use regex.

Pattern pattern = Pattern.compile("([+-]?)([\\d]+)");
String str = "+10-3+20-10-20";
Matcher m = pattern.matcher(str);
while (m.find()) {
    System.out.println(m.group(1));
    System.out.println(m.group(2));
}

This piece of code gives you all the signs (group(1)) and all the numbers (group(2)) Now you should only complete the while-loop with the proper if-clauses.

Bozho
Nice one, but I wouldn't use regex to parse something. Use a parser for that and use regex to match something.
BalusC