Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using System.Globalization;
- using System.Diagnostics;
- namespace rpn
- {
- public class Program
- {
- static void Main(string[] args)
- {
- RPN rpn = new RPN();
- Stopwatch stopwatch = Stopwatch.StartNew();
- for (int i = 0; i < 800000; ++i)
- rpn.Eval("2^3+123.43");
- stopwatch.Stop();
- Console.WriteLine(stopwatch.Elapsed);
- Console.WriteLine("wynik = {0}", rpn.Result);
- Console.ReadKey(true);
- }
- }
- public class RPN
- {
- //private const byte zero = (byte)'0';
- //private const byte nine = (byte)'9';
- [StructLayout(LayoutKind.Explicit)]
- private struct Item
- {
- [FieldOffset(0)]
- public byte operatorType;
- [FieldOffset(1)]
- public byte priority;
- [FieldOffset(2)]
- public ushort itemType;
- [FieldOffset(0)]
- public float number;
- }
- public float Result
- {
- get;
- private set;
- }
- private Item[] stack;
- private int stackCount;
- private Item[] queue;
- private int qFirst;
- private int qLast;
- public RPN()
- {
- stack = new Item[0x1000];
- queue = new Item[0x1000];
- }
- public void Eval(string data)
- {
- qFirst = qLast = 0;
- ToPostfix(data);
- Solve();
- }
- private void ToPostfix(string data)
- {
- Item item = new Item();
- for (int i = 0; i < data.Length; )
- {
- if (data[i] >= '0' && data[i] <= '9')
- {
- item.number = atof(data, ref i);
- queue[qLast++] = (item);
- }
- else
- {
- item.itemType = 0xFFFF;
- item.operatorType = (byte)data[i];
- item.priority = GetOperatorPriority(data[i]);
- while (stackCount != 0 && item.priority <= stack[stackCount - 1].priority)
- queue[qLast++] = (stack[--stackCount]);
- stack[stackCount++] = item;
- ++i;
- }
- }
- while (stackCount != 0)
- queue[qLast++] = (stack[--stackCount]);
- }
- private void Solve()
- {
- while (qLast != qFirst)
- {
- if (queue[qFirst].itemType != 0xFFFF)
- stack[stackCount++] = (queue[qFirst++]);
- else
- {
- float op2 = stack[--stackCount].number;
- float op1 = stack[stackCount - 1].number;
- byte op = (byte)queue[qFirst++].operatorType;
- Item result = stack[--stackCount];
- switch (op)
- {
- case (byte)'+':
- result.number = op1 + op2;
- break;
- case (byte)'-':
- result.number = op1 - op2;
- break;
- case (byte)'*':
- result.number = op1 * op2;
- break;
- case (byte)'/':
- result.number = op1 / op2;
- break;
- case (byte)'^':
- result.number = (float)Math.Pow((double)op1, (double)op2);
- break;
- }
- stack[stackCount++] = (result);
- }
- }
- Result = stack[--stackCount].number;
- }
- private byte GetOperatorPriority(char op)
- {
- return (byte)((op + 5) & 0x44);
- }
- private float atof(string data, ref int pos)
- {
- float value = 0;
- int len = data.Length;
- while (data[pos] >= '0' && data[pos] <= '9')
- {
- value = value * 10 + ((byte)data[pos] - '0');
- ++pos;
- if (pos >= len)
- return value;
- }
- if (data[pos] == '.')
- {
- float pow10 = 10;
- ++pos;
- while (pos < len && data[pos] >= '0' && data[pos] <= '9')
- {
- value += ((byte)data[pos] - '0') / pow10;
- pow10 *= 10;
- ++pos;
- }
- }
- return value;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement