Advertisement
Guest User

__fast__ C# RPN

a guest
Aug 5th, 2011
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.82 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using System.Globalization;
  5. using System.Diagnostics;
  6.  
  7. namespace rpn
  8. {
  9.     public class Program
  10.     {
  11.         static void Main(string[] args)
  12.         {
  13.             RPN rpn = new RPN();
  14.  
  15.             Stopwatch stopwatch = Stopwatch.StartNew();
  16.             for (int i = 0; i < 800000; ++i)
  17.                 rpn.Eval("2^3+123.43");
  18.             stopwatch.Stop();
  19.             Console.WriteLine(stopwatch.Elapsed);
  20.             Console.WriteLine("wynik = {0}", rpn.Result);
  21.  
  22.             Console.ReadKey(true);
  23.         }
  24.     }
  25.  
  26.     public class RPN
  27.     {
  28.         //private const byte zero = (byte)'0';
  29.         //private const byte nine = (byte)'9';
  30.  
  31.         [StructLayout(LayoutKind.Explicit)]
  32.         private struct Item
  33.         {
  34.             [FieldOffset(0)]
  35.             public byte operatorType;
  36.  
  37.             [FieldOffset(1)]
  38.             public byte priority;
  39.  
  40.             [FieldOffset(2)]
  41.             public ushort itemType;
  42.  
  43.             [FieldOffset(0)]
  44.             public float number;
  45.         }
  46.  
  47.         public float Result
  48.         {
  49.             get;
  50.             private set;
  51.         }
  52.  
  53.         private Item[] stack;
  54.         private int stackCount;
  55.         private Item[] queue;
  56.         private int qFirst;
  57.         private int qLast;
  58.  
  59.         public RPN()
  60.         {
  61.             stack = new Item[0x1000];
  62.             queue = new Item[0x1000];
  63.         }
  64.  
  65.         public void Eval(string data)
  66.         {
  67.             qFirst = qLast = 0;
  68.             ToPostfix(data);
  69.             Solve();
  70.         }
  71.  
  72.         private void ToPostfix(string data)
  73.         {
  74.             Item item = new Item();
  75.             for (int i = 0; i < data.Length; )
  76.             {
  77.                 if (data[i] >= '0' && data[i] <= '9')
  78.                 {
  79.                     item.number = atof(data, ref i);
  80.                     queue[qLast++] = (item);
  81.                 }
  82.                 else
  83.                 {
  84.                     item.itemType = 0xFFFF;
  85.                     item.operatorType = (byte)data[i];
  86.                     item.priority = GetOperatorPriority(data[i]);
  87.  
  88.                     while (stackCount != 0 && item.priority <= stack[stackCount - 1].priority)
  89.                         queue[qLast++] = (stack[--stackCount]);
  90.  
  91.                     stack[stackCount++] = item;
  92.                     ++i;
  93.                 }
  94.             }
  95.  
  96.             while (stackCount != 0)
  97.                 queue[qLast++] = (stack[--stackCount]);
  98.         }
  99.  
  100.         private void Solve()
  101.         {
  102.             while (qLast != qFirst)
  103.             {
  104.                 if (queue[qFirst].itemType != 0xFFFF)
  105.                     stack[stackCount++] = (queue[qFirst++]);
  106.                 else
  107.                 {
  108.                     float op2 = stack[--stackCount].number;
  109.                     float op1 = stack[stackCount - 1].number;
  110.  
  111.                     byte op = (byte)queue[qFirst++].operatorType;
  112.                     Item result = stack[--stackCount];
  113.                     switch (op)
  114.                     {
  115.                         case (byte)'+':
  116.                             result.number = op1 + op2;
  117.                             break;
  118.                         case (byte)'-':
  119.                             result.number = op1 - op2;
  120.                             break;
  121.                         case (byte)'*':
  122.                             result.number = op1 * op2;
  123.                             break;
  124.                         case (byte)'/':
  125.                             result.number = op1 / op2;
  126.                             break;
  127.                         case (byte)'^':
  128.                             result.number = (float)Math.Pow((double)op1, (double)op2);
  129.                             break;
  130.                     }
  131.  
  132.                     stack[stackCount++] = (result);
  133.                 }
  134.             }
  135.  
  136.             Result = stack[--stackCount].number;
  137.         }
  138.  
  139.         private byte GetOperatorPriority(char op)
  140.         {
  141.             return (byte)((op + 5) & 0x44);
  142.         }
  143.  
  144.         private float atof(string data, ref int pos)
  145.         {
  146.             float value = 0;
  147.  
  148.             int len = data.Length;
  149.  
  150.             while (data[pos] >= '0' && data[pos] <= '9')
  151.             {
  152.                 value = value * 10 + ((byte)data[pos] - '0');
  153.                 ++pos;
  154.  
  155.                 if (pos >= len)
  156.                     return value;
  157.             }
  158.  
  159.             if (data[pos] == '.')
  160.             {
  161.                 float pow10 = 10;
  162.                 ++pos;
  163.  
  164.                 while (pos < len && data[pos] >= '0' && data[pos] <= '9')
  165.                 {
  166.                     value += ((byte)data[pos] - '0') / pow10;
  167.                     pow10 *= 10;
  168.                     ++pos;
  169.                 }
  170.             }
  171.  
  172.             return value;
  173.  
  174.         }
  175.     }
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement