Skip to content

Instantly share code, notes, and snippets.

@tachiba
Created May 13, 2011 08:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tachiba/970233 to your computer and use it in GitHub Desktop.
Save tachiba/970233 to your computer and use it in GitHub Desktop.
Calc
import java.util.*;
/**
* 電卓.
* @author Takashi CHIBA
*/
public class Calc{
/** 出力モード:分数 */
private final int OUTPUT_FRACTION = 1;
/** 出力モード:小数 */
private final int OUTPUT_DECIMAL = 2;
/** charの数値が置いてある範囲 */
private final int CHAR_NUMBER_START = (int)'0';
private final int CHAR_NUMBER_END = (int)'9';
/** 対応する演算子 */
private final char[] supportedOperators = new char[]{'+', '-', '*', '/'};
public static void main(String... args){
args = new String[1];
args[0] = "2+3";
switch (args.length) {
case 1:
new Calc().runAsFraction(args[0]);
break;
case 2:
if (args[0] == "-d") {
new Calc().runAsDecimal(args[0]);
}
break;
case 0:
System.out.println("数式を入力してください!");
default:
System.out.println("Usage: java Calc [-d] formura");
}
}
public void runAsFraction(String in){
run(in, OUTPUT_FRACTION);
}
public void runAsDecimal(String in){
run(in, OUTPUT_DECIMAL);
}
/**
* 実行する.
* @param String in 計算式
*/
private void run(String in, int outputType){
List<Character> rpn = parse(in);
System.out.println(rpn);
// TODO テスト用に計算式を順番に出すようにしよう!
calculate(rpn);
}
/**
* 後置記法(RPN)にする.
* @param String in 計算式
*/
public List<Character> parse(String in){
int brackets = 0;
int skip = 0;
LinkedList<Character> rpn = new LinkedList<Character>();
LinkedList<Character> previousOperators = new LinkedList<Character>();
String operators = new String(supportedOperators);
// TODO 括弧のパースがまずできていない
for (int i = 0; i < in.length(); i++) {
char c = in.charAt(i);
/* is SPACE */
if (c == ' ') {
continue;
/* is ( */
} else if (c == '(') {
brackets++;
/* is ) */
} else if (c == ')') {
brackets--;
rpn.add(previousOperators.pollLast());
/* is Operators(+, -) */
} else if ("+-".indexOf(c) >= 0) {
skip = 0;
while (previousOperators.size() - brackets - skip > 0) {
rpn.add(previousOperators.pollLast());
// System.out.println(rpn.getLast());
}
/* check next operator */
for (int j = i; j < in.length(); j++) {
char d = in.charAt(j);
if (d == '*' || d == '/') {
skip++;
break;
}
}
// System.out.println("i=" + i + ", c=" + c + ",op=" + previousOperators);
previousOperators.add(c);
/* is Operators(*, /) */
} else if ("*/".indexOf(c) >= 0) {
while (previousOperators.size() - brackets - skip > 0) {
rpn.add(previousOperators.pollLast());
}
previousOperators.add(c);
/* is numerical */
} else if ((int)c >= CHAR_NUMBER_START && (int)c <= CHAR_NUMBER_END) {
rpn.add(c);
}
}
rpn.add(previousOperators.pollLast());
if (skip == 1) rpn.add(previousOperators.pollLast());
System.out.println(previousOperators);
return rpn;
}
/**
* 計算する.
*/
public int calculate(List<Character> rpn){
for (int i = 2; i < rpn.size(); i++) {
char c = rpn.get(i);
// TODO 条件減らせる気がする。
if (c < '0' || c > '9') {
// TODO 本当に動く?
int num1 = rpn.get(i - 1) - '0';
int num2 = rpn.get(i - 2) - '0';
rpn.remove(i - 2);
rpn.remove(i - 2);
switch (c) {
case '+':
rpn.add(i, num1 + num2);
case '-':
case '*':
case '/':
}
}
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment