1

i am not sure how can i read a number like 10 and above for a char array, i am converting from infix to postfix , currently i am able to do so for single digits however when it comes to multiple digits when evaluating the postfix equation it would be a wrong answer. for example 10+13+4 it would give a wrong answer but 1+3+4 it would be correct.

        //class main 
        calcParser calc = new calcParser("13+20+3+4");
               calc.toPostfix();
               calc.displayPostfix();
               calc.evaluatePostfix();
               calc.displayResult();
       // result for above would be
    1320+3+4+
    9.0

// class calcParser
      public void toPostfix()
        {
          for(char c : originalExp.toCharArray())
          {
              switch(c)
              {
                  case '0': case '1': case '2': case '3': case '4': case '5':
                  case '6': case '7': case '8': case '9':
                  postfixExp.append(c);
                  break;

                  case '+': case '-':
                  if(postfixStack.empty())
                  {
                      postfixStack.push(c);
                  }
                  else
                  {
                      if((postfixStack.peek().equals(c)))
                      {
                          postfixExp.append(postfixStack.pop());
                          postfixStack.push(c);
                      }
                      else
                      {
                          postfixExp.append(postfixStack.pop());
                          postfixStack.push(c);
                      }

                  }
                  break;
                }
            }
            while(!postfixStack.empty())
            {
             postfixExp.append(postfixStack.pop());
            }
          }

        public void evaluatePostfix()
        {
           String postfix = postfixExp.toString();
           for(char c : postfix.toCharArray())
           {
               switch (c)
               {
                  case '0': case '1': case '2': case '3': case '4': case '5':
                  case '6': case '7': case '8': case '9':
                  postfixResultStack.push(c);
                  break;

                  case '+':
                  firstOperand = Double.parseDouble(postfixResultStack.pop().toString());
                   secondOperand = Double.parseDouble(postfixResultStack.pop().toString());
                  postfixResultStack.push(firstOperand + secondOperand);
                  break;

                  case '-':
                  firstOperand = Double.parseDouble(postfixResultStack.pop().toString());
                  secondOperand = Double.parseDouble(postfixResultStack.pop().toString());
                  postfixResultStack.push(firstOperand - secondOperand);
                  break;

               }

           }

        }
sutoL
  • 1,697
  • 10
  • 27
  • 45

4 Answers4

3

Just scan while you keep getting digits. But you'll have to abandon the idea of using for (char : ...). You need a way to advance the current position explicitly.

user207421
  • 289,834
  • 37
  • 266
  • 440
  • so i will need to abandon the char[] too? since the char[] only take a literal it cannot read multiple digit as one. – sutoL Jul 28 '10 at 06:18
  • That question doesn't make any sense to me. – user207421 Jul 28 '10 at 06:31
  • sorry if i am not clear, you said to abandon the for each loop, does it mean i will also have to abandon converting the expression string into a char array too? – sutoL Jul 28 '10 at 06:37
  • I didn't say so, and I don't understand what your reasons may be for thinking so. – user207421 Jul 28 '10 at 09:17
1

how about using a StringTokenizer? split the string using the operand as the token then use Integer.parseInt() to parse the numbers?

Ok i just come up with something that solves your homework. It's ugly but working. :)

public static void main(String[] args) {
    String expression = "10+10+2-10-1";
    List<String> positiveOperands = new ArrayList<String>();
    StringTokenizer st = new StringTokenizer(expression, "+");
    while(st.hasMoreElements()){
        positiveOperands.add(st.nextToken());
    }
    int total = 0;
    for(String posOperand: positiveOperands){
        // evaluate subtraction
        StringTokenizer st2 = new StringTokenizer(posOperand, "-");
        int a = 0;
        if(st2.hasMoreElements()) a = Integer.parseInt(st2.nextToken());
        while(st2.hasMoreElements()){
            a-=Integer.parseInt(st2.nextToken());
        }
        total+=a;
    }
    System.out.println(total);
}
demotics2002
  • 712
  • 1
  • 7
  • 19
1

Here's a solution that uses java.util.Scanner:

Scanner sc = new Scanner("12+3 - 456").useDelimiter("\\b");
while (sc.hasNext()) {
    if (sc.hasNextInt()) {
        int num = sc.nextInt();
        System.out.printf("Got an int [%s]%n", num);
    } else {
        String op = sc.next().trim();
        System.out.printf("Got an op [%s]%n", op);
    }
}

The above prints (as seen on ideone.com):

Got an int [12]
Got an op [+]
Got an int [3]
Got an op [-]
Got an int [456]

The delimiter is \b (the backslash doubled in a Java string literal), which is the "word boundary". It occurs, among other places, between word characters \w (which digits are) and non-word characters \W (which operators are).

As a caveat, this delimiter regex will not properly tokenize floating point numbers with decimal points, but more specific regex can be written to address those issues should they be needed.

Note also the convenience of using Scanner to parse the String into int; you can do this in such a way that it will never throw an exception (e.g. by first asserting that it hasNextInt()).

Related questions

References

Community
  • 1
  • 1
polygenelubricants
  • 348,637
  • 121
  • 546
  • 611
  • thanks, the \w delimiter is what im looking at, however in the later stages if i were to implement it to include decimal points 10.5+20 would it be hard? – sutoL Jul 28 '10 at 08:29
  • @kyrogue: Not hard at all if you know regex. You may have to use zero-width matching regex with assertions. See e.g. http://stackoverflow.com/questions/2406633/can-you-use-zero-width-matching-regex-in-string-split/2406862#2406862 , http://stackoverflow.com/questions/2819933/java-split-is-eating-my-characters/2820009#2820009 , etc. – polygenelubricants Jul 28 '10 at 08:35
0

You probably want to work in terms of Token's not char's.

Have the first stage of your parser consume a stream of char's and generate a stream of Tokens, and then have the next stages generate/execute the stack.

So you have:

"10+11 + 4" becomes

List { Number(10), Operator(+), Number(11), Operator(+), Number(4) }

Then you use your existing toPostFix() (modified to work on tokens) build the stack, then print/evaluate/etc.

To generate the tokens the traditional approach is a series of regexes applied in order with the first match being used to generate a Token.

Recurse
  • 3,467
  • 1
  • 20
  • 34