目次

 

 

 

 

 

 

 

Top >コンソール・アプリケーション集

逆ポーランド記法電卓 Java

import java.io.*;

/**
* 入力処理の結果
*/

enum OPERATION
{
    PLUS,       // 足し算
    MINUS,      // 引き算
    MULTIPLY,   // 掛け算
    DIVIDE,     // 割り算
    INVERSION,  // 符号反転
    CLEAR,      // クリア
    ENTER,      // 入力
    EXIT        // 終了
}

/**
* スタックのクラス
*/

class CalcStack
{
    private static final int StackSize = 10;   // スタックの大きさ

    private double[] mValues;   // 数値配列
    private int mCount;         // 要素数

    /**
    * コンストラクタ
    */

    public CalcStack()
    {
        mValues = new double[StackSize];
        mCount = 0;
    }

    /**
    * プッシュ
    *
    * @param value プッシュする数値
    */

    public void Push(double value) throws Exception
    {
        if (mCount >= StackSize)
            throw new Exception("Stack がオーバーフローしました。");

        mValues[mCount++] = value;
    }

    /**
    * ポップ
    *
    * @return ポップされた数値
    */

    public double Pop() throws Exception
    {
        if (mCount <= 0)
            throw new Exception("Stack が空です。");

        return mValues[--mCount];
    }

    /**
    * 要素数を取得する
    *
    * @return 要素数
    */

    public int Count()
    {
        return mCount;
    }

    /**
    * 指定されたインデックス位置にある要素を返す。
    *
    * @param idx 取得する要素の、0 から始まるインデックス
    * @return 指定された位置にある要素
    */

    public double ElementAt(int idx) throws Exception
    {
        if (idx < 0 || idx >= mCount)
            throw new Exception("パラメータが正しくありません。");

        return mValues[mCount - idx - 1];
    }
}

/**
* 入力処理
*/

class RpnCalc
{
    private CalcStack mStack = new CalcStack();

    /**
    * 入力処理
    *
    * @return 入力処理の結果
    */

    private OPERATION Input() throws Exception
    {
        BufferedReader br = new BufferedReader(
                            new InputStreamReader( System.in ) );

        String input = br.readLine();   // 1行入力

        String numbers = "";
        OPERATION ope = OPERATION.ENTER;

        forint i = 0 ; i < input.length() ; i++ )
        {
            char ch = input.charAt(i);

            if (('0' <= ch && ch <= '9') || ch == '.')
            {
                // 数字と小数点の場合

                numbers += ch;
            }
            else
            {
                // 演算の場合

                if (ch == '+')
                    ope = OPERATION.PLUS;
                else if (ch == '-')
                    ope = OPERATION.MINUS;
                else if (ch == '*')
                    ope = OPERATION.MULTIPLY;
                else if (ch == '/')
                    ope = OPERATION.DIVIDE;
                else if (ch == '!')
                    ope = OPERATION.INVERSION;
                else if (ch == 'c'|| ch == 'C')
                    ope = OPERATION.CLEAR;
                else if (ch == 'q' || ch == 'Q')
                    ope = OPERATION.EXIT;

                break;  // 入力を終了
            }
        }

        // 数字の入力があれば、スタックにプッシュする。
        if (numbers.length() > 0)
            mStack.Push(Double.parseDouble(numbers));

        return ope;
    }

    /**
    * 電卓画面を表示
    */

    private void ShowCalculator() throws Exception
    {
        final String body = "\n"
                + "*** RPN Calculator *******************************\n"
                + "*    +:加 -:減 *:乗 /:除 !:符号 c:削除 q:終了    *\n"
                + "*                                                *";

        System.out.println( body );

        // スタックの内容を表示する

        for (int i = mStack.Count(); i > 0; i--)
            System.out.printf("* %2d: %f\n", i, mStack.ElementAt(i - 1) );

        System.out.print(">");
    }

    /**
    * 電卓の実行
    */

    public void Run()
    {
        for (; ; )
        {
            OPERATION operation = OPERATION.EXIT;

            try
            {
                // 電卓画面を表示
                ShowCalculator();

                 // 入力
               operation = Input();

                 // 必要な個数の数値をポップして演算を施し、結果をプッシュする

                 if (operation == OPERATION.INVERSION || operation == OPERATION.CLEAR)
                {
                    // 必要とする数値が1つの操作

                    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)  // 0での除算
                            System.out.println("\nDivide by Zero!");
                        else
                            mStack.Push(n2 / n1);
                    }
                }
                else if (operation == OPERATION.EXIT)
                {
                    // プログラムの終了
                    break;
                }
            }
            catch (Exception ex)
            {
                System.out.println("\n" + ex.getMessage());
            }
        }

    }

    /**
    *   main
    */

    public static void main( String[] args )
    {
        RpnCalc calc = new RpnCalc();

        calc.Run();
    }
}
AKABAS
NEZEN