1

I write an rpn, with a struktogram.

Newest Problem: It is'nt work correctly now.

If input string is "5 + ((1 + 2) * 4) - 3"

My output is: 5 1 2 + 4 * 3 - +

I have to got this result: 5 1 2 + 4 * + 3 -

Edited the source

*That was the original problem, but helped me, and now the original mistakes fixed: *,

At the debug when the loop or int i = 12, the c value is 0\0 or something else and this value is added to output (name: formula) string as a '(' bracket. And I don't know why. And the last '-' operation symbol, don't added to (or not look) at the end of output string (formula) I misgave this problem cause by the '('. I tried the program with other string input value, but always put an '(' to my string, and I don't know why... I saw that It was independt about the numbers of bracket. Always only one '(' add to my string...*) Yes, in english LengyelFormula = rpn (it is hungarian)*

static void Main(string[] args)
    {
        String str = "5 + ( ( 1 + 2 ) *  4 ) −3";
        String result=LengyelFormaKonvertalas(str);
        Console.WriteLine(result.ToString());
        Console.ReadLine();
    }

    static String LengyelFormaKonvertalas(String input) // this is the rpn method
    {
       Stack stack = new Stack();
       String str = input.Replace(" ",string.Empty);
       StringBuilder formula = new StringBuilder();
       for (int i = 0; i < str.Length; i++)
       {
           char x=str[i];
           if (x == '(')
               stack.Push(x);
           else if (IsOperandus(x)) // is it operand
           {
               formula.Append(x);
           }
           else if (IsOperator(x))  // is it operation
           {
               if (stack.Count>0 && (char)stack.Peek()!='(' && Prior(x)<=Prior((char)stack.Peek()) )
               {
                   char y = (char)stack.Pop();
                   formula.Append(y);
               }
               if (stack.Count > 0 && (char)stack.Peek() != '(' && Prior(x) < Prior((char)stack.Peek()))
               {
                   char y = (char)stack.Pop();
                   formula.Append(y);
               }
               stack.Push(x);
           }
           else
           {
              char y=(char)stack.Pop();
              if (y!='(')
              {
                  formula.Append(y);
              }
           }
       }
       while (stack.Count>0)
       {
           char c = (char)stack.Pop();
           formula.Append(c);
       }
       return formula.ToString();
    }

    static bool IsOperator(char c)
    {
        return (c=='-'|| c=='+' || c=='*' || c=='/');
    }
    static bool IsOperandus(char c)
    {
        return (c>='0' && c<='9' || c=='.');
    }
    static int Prior(char c)
    {
        switch (c)
        {
            case '=':
                return 1;
            case '+':
                return 2;
            case '-':
                return 2;
            case '*':
                return 3;
            case '/':
                return 3;
            case '^':
                return 4;
            default:
                throw new ArgumentException("Rossz paraméter");                                          
        }
    }
}
blaces
  • 497
  • 3
  • 10
  • 24
  • In the case that x is an operator, you correctly check whether the top of the stack is an other operator of lower/equal precedence, but that should be a loop instead of a single test. (or I guess it's a double check now - but it should be a loop) – harold Oct 16 '11 at 15:46
  • Sorry, I am a beginner programmer and english learner :). What do you understand by "should be a loop instead of a single test"? I don't know what is single test in my program :( – blaces Oct 16 '11 at 15:51
  • 1
    Well you're implementing this: http://en.wikipedia.org/wiki/Shunting-yard_algorithm right? Right after the use of "IsOperator" you have `if(stack.Count > 0 && .. `, that should be `while`. – harold Oct 16 '11 at 16:04
  • I've rewriten, that you say ` ( if(stack.Count ... to while(stack.Count...) ` But it didn1t solve the problem. The bracket still add to string. (The struktogram - algorithm in the pdf, about the first quarter Maybe it is the Shunting-yard algorithm... I don't know exactly I used this [link](http://nik.uni-obuda.hu/nagya/PPT_Esti_0809tavasz/GenerikusTipus/lengyelforma.pdf) and it hungarian called the polish notation, maybe that university's prof did a mistake :) – blaces Oct 16 '11 at 16:14

3 Answers3

3
using System;
using System.Collections.Generic;
using System.Text;

class Sample {
    static void Main(string[] args){
        String str = "5 + ( ( 1 + 2 ) *  4 ) -3";
        String result=LengyelFormaKonvertalas(str);
        Console.WriteLine(result);
        Console.ReadLine();
    }

    static String LengyelFormaKonvertalas(String input){
       Stack<char> stack = new Stack<char>();
       String str = input.Replace(" ", string.Empty);
       StringBuilder formula = new StringBuilder();
       for (int i = 0; i < str.Length; i++){
           char x=str[i];
           if (x == '(')
               stack.Push(x);
           else if (x == ')'){
               while(stack.Count>0 && stack.Peek() != '(')
                   formula.Append(stack.Pop());
               stack.Pop();
           } else if (IsOperandus(x)){
               formula.Append(x);
           } else if (IsOperator(x)) {
               while(stack.Count>0 && stack.Peek() != '(' && Prior(x)<=Prior(stack.Peek()) )
                   formula.Append(stack.Pop());
               stack.Push(x);
           }
           else {
              char y= stack.Pop();
              if (y!='(') 
                  formula.Append(y);
           }
       }
       while (stack.Count>0) {
           formula.Append(stack.Pop());
       }
       return formula.ToString();
    }

    static bool IsOperator(char c){
        return (c=='-'|| c=='+' || c=='*' || c=='/');
    }
    static bool IsOperandus(char c){
        return (c>='0' && c<='9' || c=='.');
    }
    static int Prior(char c){
        switch (c){
            case '=':
                return 1;
            case '+':
                return 2;
            case '-':
                return 2;
            case '*':
                return 3;
            case '/':
                return 3;
            case '^':
                return 4;
            default:
                throw new ArgumentException("Rossz parameter");                                          
        }
    }
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
0

In IsOperator, you check c == '-'.
But in the string, you write −3.
− isn't the same character than -
I don't know about Polish stuff so maybe I'm missing something, but that's why no '-' operator is printed, it fails the IsOperator check and goes into the else clause, which doesn't add it to formula.

Pierre
  • 56
  • 2
  • Thanks, it is true :) there is another symbol, now it is print it, and now it is print 2 '(' symbol – blaces Oct 16 '11 at 16:31
  • 1
    They are added in the last while, you could simply add a "if (c != '(')" before the last formula.Append. Then run many tests to see if it's fine. I'm not familiar with this algorithm so I don't know if there is a cleaner fix. – Pierre Oct 16 '11 at 16:38
0

When you get a ), you should pop all operators and add them to your formula until you reach a (, and pop that '(' as well.

When you get an operator, you should only pop the stack and add this operator to the formula if its priority is greater than or equal to that of x. Your second check is redundant because it is already covered by the first.

As a general rule: try your program with some simple inputs like 1+2+3, 1+2-3, 1*2+3 and 1+2*3 and see if you get the right result. Testing systematically like that should help you find errors faster.

Jeffrey Sax
  • 10,253
  • 3
  • 29
  • 40