Advertisement
ArXen42

Разбор выражений

Apr 13th, 2016
363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.33 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. /// <summary>
  6. /// Простая реализация стека на основе массива.
  7. /// </summary>
  8. /// <typeparam name="T">Тип элемента</typeparam>
  9. public sealed class CustomStack<T> : IEnumerable<T>
  10. {
  11.     public CustomStack() : this(0)
  12.     {
  13.     }
  14.  
  15.     public CustomStack(Int32 capacity)
  16.     {
  17.         arr = new T[capacity];
  18.         lastIndex = -1;
  19.     }
  20.  
  21.     public T Peek()
  22.     {
  23.         if (lastIndex > -1)
  24.             return arr[lastIndex];
  25.         else
  26.             throw new InvalidOperationException("Stack empty.");
  27.     }
  28.  
  29.     public void Push(T value)
  30.     {
  31.         lastIndex++;
  32.  
  33.         if (arr.Length < lastIndex + 1)
  34.             this.Capacity = lastIndex > 0 ? lastIndex * 2 : 1;
  35.  
  36.         arr[lastIndex] = value;
  37.     }
  38.  
  39.     public T Pop()
  40.     {
  41.         if (lastIndex > -1)
  42.         {
  43.             lastIndex--;
  44.             return arr[lastIndex + 1];
  45.         }
  46.         else
  47.             throw new InvalidOperationException("Stack empty.");
  48.     }
  49.  
  50.     IEnumerator IEnumerable.GetEnumerator()
  51.     {
  52.         return new CustomStackEnumerator(this);
  53.     }
  54.  
  55.     IEnumerator<T> IEnumerable<T>.GetEnumerator()
  56.     {
  57.         return new CustomStackEnumerator(this);
  58.     }
  59.  
  60.     public int Count
  61.     {
  62.         get
  63.         {
  64.             return lastIndex + 1;
  65.         }
  66.     }
  67.  
  68.     public int Capacity
  69.     {
  70.         get
  71.         {
  72.             return arr.Length;
  73.         }
  74.         set
  75.         {
  76.             if (value >= Count)
  77.                 Array.Resize<T>(ref arr, value);
  78.             else
  79.                 throw new ArgumentOutOfRangeException("Capacity was less than the current size.");
  80.         }
  81.     }
  82.  
  83.     private T[] arr;
  84.     private int lastIndex;
  85.  
  86.     private struct CustomStackEnumerator : IEnumerator<T>, IEnumerator
  87.     {
  88.         public CustomStackEnumerator(CustomStack<T> stack)
  89.         {
  90.             this.stack = stack;
  91.             this.index = -1;
  92.         }
  93.  
  94.         T IEnumerator<T>.Current
  95.         {
  96.             get
  97.             {
  98.                 return stack.arr[index];
  99.             }
  100.         }
  101.  
  102.         object IEnumerator.Current
  103.         {
  104.             get
  105.             {
  106.                 return stack.arr[index];
  107.             }
  108.         }
  109.  
  110.         public bool MoveNext()
  111.         {
  112.             index++;
  113.             return index < stack.Count;
  114.         }
  115.  
  116.         public void Reset()
  117.         {
  118.             index = -1;
  119.         }
  120.         void IDisposable.Dispose()
  121.         {
  122.         }
  123.  
  124.         private CustomStack<T> stack;
  125.         private int index;
  126.     }
  127. }
  128.  
  129. using System;
  130. using System.Collections;
  131. using System.Collections.Generic;
  132.  
  133. public static class SimpleCalculator
  134. {
  135.     public static double CalculateString(string expression)
  136.     {
  137.         translatorStack = new Stack<string>();
  138.         interpreterStack = new Stack<Double>();
  139.         translatorStack.Push(EmptyOperation);
  140.  
  141.         foreach (string s in  (expression + ' ' + EmptyOperation).Split(' '))
  142.         {
  143.             double value;
  144.             if (Double.TryParse(s, out value))
  145.             {
  146.                 interpreterStack.Push(value);
  147.             }
  148.             else
  149.             {
  150.                 string lastOperationInStack = translatorStack.Peek();
  151.                 transitionTable[VerticalIndexesMap.IndexOf(lastOperationInStack), HorizontalIndexesMap.IndexOf(s)](s);
  152.             }
  153.         }
  154.  
  155.         return interpreterStack.Peek();
  156.     }
  157.  
  158.     private const string EmptyOperation = "$";
  159.     private const string OpeningBracket = "(";
  160.     private const string Plus = "+";
  161.     private const string Minus = "-";
  162.     private const string Multiplication = "*";
  163.     private const string Division = "/";
  164.     private const string ClosingBracket = ")";
  165.  
  166.     private static Dictionary<String, Func<double, double, double>> arithmeticalFunctions = new Dictionary<string, Func<double, double, double>>()
  167.     {
  168.         {Plus, (a, b) => a + b},
  169.         {Minus, (a, b) => a - b},
  170.         {Multiplication, (a, b) => a * b},
  171.         {Division, (a, b) => a / b}
  172.     };
  173.  
  174.     private static Stack<String> translatorStack;
  175.     private static Stack<Double> interpreterStack;
  176.  
  177.     private static Action<string> f1 = (string inputOperation) =>
  178.     {
  179.         translatorStack.Push(inputOperation);
  180.     };
  181.     private static Action<String> f2 = (string inputOperation) =>
  182.     {
  183.         string lastOperationInStack = translatorStack.Pop();
  184.         double operand2 = interpreterStack.Pop();
  185.         double operand1 = interpreterStack.Pop();
  186.  
  187.         double result = arithmeticalFunctions[lastOperationInStack](operand1, operand2);
  188.         interpreterStack.Push(result);
  189.         translatorStack.Push(inputOperation);
  190.     };
  191.     private static Action<String> f3 = (string inputOperation) =>
  192.     {
  193.         translatorStack.Pop();
  194.     };
  195.     private static Action<String> f4 = (string inputOperation) =>
  196.     {
  197.         string lastOperationInStack = translatorStack.Pop();
  198.         double operand2 = interpreterStack.Pop();
  199.         double operand1 = interpreterStack.Pop();
  200.  
  201.         double result = arithmeticalFunctions[lastOperationInStack](operand1, operand2);
  202.         interpreterStack.Push(result);
  203.  
  204.         lastOperationInStack = translatorStack.Peek();
  205.         transitionTable[VerticalIndexesMap.IndexOf(lastOperationInStack), HorizontalIndexesMap.IndexOf(inputOperation)](inputOperation);
  206.     };
  207.     private static Action<String> f5 = (string inputOperation) =>
  208.     {
  209.         throw new Exception("Invalid input string.");
  210.     };
  211.     private static Action<String> f6 = (string inputOperation) =>
  212.     {
  213.     };
  214.  
  215.     private const string HorizontalIndexesMap = EmptyOperation + OpeningBracket + Plus + Minus + Multiplication + Division + ClosingBracket;
  216.     private const string VerticalIndexesMap = EmptyOperation + OpeningBracket + Plus + Minus + Multiplication + Division;
  217.  
  218.     private static readonly Action<String>[,] transitionTable = new Action<String>[,]
  219.     {
  220.         {f6,f1,f1,f1,f1,f1,f5},
  221.         {f5,f1,f1,f1,f1,f1,f3},
  222.         {f4,f1,f2,f2,f1,f1,f4},
  223.         {f4,f1,f2,f2,f1,f1,f4},
  224.         {f4,f1,f4,f4,f2,f2,f4},
  225.         {f4,f1,f4,f4,f2,f2,f4}
  226.     };
  227. }
  228.  
  229. public class Program
  230. {
  231.     public static void Main(String[] args)
  232.     {
  233.         SimpleCalculator.CalculateString("1 + 2");
  234.     }
  235. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement