逆ポーランド記法電卓 C#
using System;
using System.Collections.Generic;
using System.Linq;
enum OPERATION : int
{
PLUS,
MINUS,
MULTIPLY,
DIVIDE,
INVERSION,
CLEAR,
ENTER,
EXIT
};
class CalcStack
{
private const int StackSize = 10;
private double[] mValues;
private int mCount;
public CalcStack()
{
mValues = new double[StackSize];
mCount = 0;
}
public void Push(double value)
{
if (mCount >= StackSize)
throw new Exception("Stack がオーバーフローしました。");
mValues[mCount++] = value;
}
public double Pop()
{
if (mCount <= 0)
throw new Exception("Stack が空です。");
return mValues[--mCount];
}
public int Count
{
get { return mCount; }
}
public double ElementAt(int idx)
{
if (idx < 0 || idx >= mCount)
throw new Exception("パラメータ正しくありません。");
return mValues[mCount - idx - 1];
}
}
class RpnCalc
{
private CalcStack mStack = new CalcStack();
private OPERATION Input()
{
string numbers = "";
OPERATION ope = OPERATION.ENTER;
for (; ; )
{
ConsoleKeyInfo kinfo = Console.ReadKey();
if (('0' <= kinfo.KeyChar && kinfo.KeyChar <= '9') || kinfo.KeyChar == '.')
{
numbers += kinfo.KeyChar;
}
else
{
if (kinfo.KeyChar == '+')
ope = OPERATION.PLUS;
else if (kinfo.KeyChar == '-')
ope = OPERATION.MINUS;
else if (kinfo.KeyChar == '*')
ope = OPERATION.MULTIPLY;
else if (kinfo.KeyChar == '/')
ope = OPERATION.DIVIDE;
else if (kinfo.KeyChar == '!')
ope = OPERATION.INVERSION;
else if (kinfo.Key == ConsoleKey.C)
ope = OPERATION.CLEAR;
else if (kinfo.Key == ConsoleKey.Q)
ope = OPERATION.EXIT;
break;
}
}
if (!string.IsNullOrWhiteSpace(numbers))
mStack.Push(double.Parse(numbers));
return ope;
}
private void ShowCalculator()
{
const string body = "\n"
+ "*** RPN Calculator *******************************\n"
+ "* +:加 -:減 *:乗 /:除 !:符号 c:削除 q:終了 *\n"
+ "* *";
Console.WriteLine(body);
for (int i = mStack.Count; i > 0; i--)
Console.WriteLine("* {0:00}: {1}", i, mStack.ElementAt(i - 1));
Console.Write(">");
}
public void Run()
{
for (; ; )
{
OPERATION operation;
try
{
ShowCalculator();
operation = Input();
if (operation == OPERATION.INVERSION || operation == OPERATION.CLEAR)
{
double n = mStack.Pop();
if (operation == OPERATION.INVERSION)
mStack.Push(n * (-1.0));
}
else if (operation == OPERATION.PLUS || operation == OPERATION.MINUS
|| operation == OPERATION.MULTIPLY || operation == OPERATION.DIVIDE)
{
double n1 = mStack.Pop();
double n2 = mStack.Pop();
if (operation == OPERATION.PLUS)
mStack.Push(n1 + n2);
else if (operation == OPERATION.MINUS)
mStack.Push(n2 - n1);
else if (operation == OPERATION.MULTIPLY)
mStack.Push(n1 * n2);
else if (operation == OPERATION.DIVIDE)
{
if (n1 == 0.0)
Console.WriteLine("\nDivide by Zero!");
else
mStack.Push(n2 / n1);
}
}
else if (operation == OPERATION.EXIT)
{
break;
}
}
catch (Exception ex)
{
Console.WriteLine("\n" + ex.Message);
}
}
}
static void Main(string[] args)
{
RpnCalc calc = new RpnCalc();
calc.Run();
}
}