2017-05-25 5 views
0

J'ai déjà trouvé différentes solutions sur Stackoverflow, mais il y avait des choses que je ne comprenais pas. Quelle est la meilleure méthode pour calculer la sortie de, par exemple: ((1+ (4 * (2 + 3))) + ((2 + 3) * (4 * 5)))?Comment calculer la sortie d'Infix-Expression en utilisant des piles en C#

Ma méthode semble que suivant, mais je sais qu'il ya beaucoup d'erreurs dans ce:

public static int ComputeInfix(string infix) { 
     Stack<char> operatorstack = new Stack<char>(); 
     Stack<int> operandstack = new Stack<int>(); 
     for(int j = 0; j < infix.Length; j++) { 
      char c = infix[j]; 
      if (c => 0 && c <= 9) { 
       operandstack.Push(c); 
      } 
      else if ((c == '+' || c == '*' || c == '/' || c == '-')) { 
       if (operatorstack.IsEmpty()) { 
        operatorstack.Push(c); 
       } 
       else { 
        if (operatorstack.Peek() != '*' || operatorstack.Peek() != '/') { 
         operatorstack.Push(c); 
        } 
       } 
      } 
      else if (c == '(') { 
       operatorstack.Push(c); 
      } 
      else if (c == ')') { 
       operatorstack.Pop(); 
      } 
     } 
     return infix; 
    } 

changé à:

Stack<char> operatorstack = new Stack<char>(); 
     Stack<char> operandstack = new Stack<char>(); 
     for(int j = 0; j < infix.Length; j++) { 
      char c = infix[j]; 
      if (c => '0' && c <= '9') { 
       operandstack.Push(c); 
      } 

Mais obtenir l'erreur:

Infix.cs(16,8): error CS0136: A local variable named c' cannot be declared in this scope because it would give a different meaning to c', which is already used in a `parent or current' scope to denote something else

+0

[Calculator.net?](http://weblogs.asp.net/pwelter34/archive/2007/05/05/calculator-net-calculator-that-evaluates-math-expressions.aspx) – PoweredByOrange

+0

Maintenant modifié à: '(c => '0' && c <= '9')' – Patzi0207

+0

La ligne 'c => 0 && c <= 9' est fausse. La variable 'c' est un char. Si vous voulez le nombre entier de ce char, vous devez l'analyser, comme ceci 'int nombre = int.Parse (c.ToString());' –

Répondre

0

Depuis que j'ai passé du temps à l'écrire, voici ma solution:

public static int ComputeInfix(string infix) { 
    var operatorstack = new Stack<char>(); 
    var operandstack = new Stack<int>(); 

    var precedence = new Dictionary<char, int> { { '(', 0 }, { '*', 1 }, { '/', 1 }, { '+', 2 }, { '-', 2 }, { ')', 3 } }; 

    foreach (var ch in infix) { 
     switch (ch) { 
      case var digit when Char.IsDigit(digit): 
       operandstack.Push(Convert.ToInt32(digit.ToString())); 
       break; 
      case var op when precedence.ContainsKey(op): 
       var keepLooping = true; 
       while (keepLooping && operatorstack.Count > 0 && precedence[ch] > precedence[operatorstack.Peek()]) { 
        switch (operatorstack.Peek()) { 
         case '+': 
          operandstack.Push(operandstack.Pop() + operandstack.Pop()); 
          break; 
         case '-': 
          operandstack.Push(-operandstack.Pop() + operandstack.Pop()); 
          break; 
         case '*': 
          operandstack.Push(operandstack.Pop() * operandstack.Pop()); 
          break; 
         case '/': 
          var divisor = operandstack.Pop(); 
          operandstack.Push(operandstack.Pop()/divisor); 
          break; 
         case '(': 
          keepLooping = false; 
          break; 
        } 
        if (keepLooping) 
         operatorstack.Pop(); 
       } 
       if (ch == ')') 
        operatorstack.Pop(); 
       else 
        operatorstack.Push(ch); 
       break; 
      default: 
       throw new ArgumentException(); 
     } 
    } 

    if (operatorstack.Count > 0 || operandstack.Count > 1) 
     throw new ArgumentException(); 

    return operandstack.Pop(); 
}