解答例 - j1.lesson12.SimpleCalc

package j1.lesson12;

import java.io.*;

/**
 * 課題1204 - 解答例.
 
 @author arakawa
 @version $Id: SimpleCalc_java.rps,v 1.1 2006/03/06 12:56:15 java2005 Exp $
 */
public class SimpleCalc {

    /**
     * 1桁の数字, '+', '-'からなる式を計算し、その結果を表示するプログラム。
     * 以下の擬似コードで表される。
     <pre>
     * プログラム全体
     *     print "式を入力:"
     *     expression = コンソール入力 (文字列)
     *     if is-valid(expression)
     *         print calculate(expression)
     *     else
     *         print &quot;不正な文字列です&quot;
     </pre>
     @param args 無視される
     @throws IOException 入力中に例外が発生した場合
     */
    // プログラム全体
    public static void main(String[] argsthrows IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        // print "式を入力:"
        System.out.print("式を入力:");
        
        // expression = コンソール入力 (文字列)
        String expression = reader.readLine();

        // if is-valid(expression)
        if (isValid(expression)) {
            // print calculate(expression)
            System.out.println(calculate(expression));
        }
        // else
        else {
            // print "不正な文字列です"
            System.out.println("不正な文字列です");
        }
    }

    /**
     * 指定された文字列が 数値, '+', '-' のいずれかからのみで成るか調べる。
     <pre>
     * is-valid(expression)
     *     for c in expressionのすべての文字
     *         if c が数値でも'+'でも'-'でもない
     *             false を返す
     *     true を返す
     </pre>
     @param expression 有効であるか調べられる文字列
     @return 数値, '+', '-' のいずれかからのみ成る場合は <code>true</code>
     */
    // is-valid(expression)
    public static boolean isValid(String expression) {
        // for c in expressionのすべての文字
        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);

            // if c が数値でも'+'でも'-'でもない
            if (!Character.isDigit(c&& c != '+' && c != '-') {
                // false を返す
                return false;
            }
        }

        // true を返す
        return true;
    }

    /**
     * 1桁の数字,'+','-'からなる式を計算した結果を返す。
     * 以下の擬似コードで表される。
     <pre>
     * calculate(expression)
     *     result = 0
     *     operator = '+'
     *     for i = 0 to expressionの長さ-1 まで
     *         c = expression の i 文字目
     *         if c が数字
     *             value = c を数値としてみなした値
     *             result = result &lt;operator&gt; value
     *         else if c が '+'
     *             operator = '+'
     *         else if c が '-'
     *             operator = '-'
     *     result を返す
     </pre>
     @param expression 式
     @return 式を計算した結果
     @see Character#isDigit(char)
     @see Character#getNumericValue(char)
     */
    // calculate(expression)
    public static int calculate(String expression) {
        // result = 0
        int result = 0;
        // operator = '+'
        char operator = '+';

        // for i = 0 to expressionの長さ-1 まで
        for (int i = 0; i < expression.length(); i++) {
            // c = expression の i 文字目
            char c = expression.charAt(i);

            // if c が数字
            if (Character.isDigit(c)) {
                // value = c を数値としてみなした値
                int value = Character.getNumericValue(c);
                // result = result <operator> value
                result = operate(result, operator, value);
            }
            // else if c が '+'
            else if (c == '+') {
                // operator = '+'
                operator = '+';
            }
            // else if c が '-'
            else if (c == '-') {
                // operator = '-'
                operator = '-';
            }
            // else
            else {
                // 無視する
            }
        }

        // result を返す
        return result;
    }

    /**
     * 2項の演算を実行する。 '+' と '-' についてサポートしている。
     @param left 被演算数
     @param operator 演算子
     @param right 演算数
     @return 演算した結果
     */
    public static int operate(int left, char operator, int right) {
        if (operator == '+') {
            return left + right;
        }
        else if (operator == '-') {
            return left - right;
        }
        else {
            return -1;
        }
    }
}