Fraction Class
Fractionクラスは、有理数をあらわすクラスです。
サンプルアプレット
Fraction クラスのソースを見る
import java.util.*; //Stack //import java.lang.Number; import java.util.regex.*; import java.io.*; enum State { NUMBER, OPERATOR, PARENTHESES }; //enum OpKind { add, subtract, multiply, divide }; class Fraction extends Number implements Cloneable, Comparable
{ private int numerator; private int denominator; public Fraction(int n){ numerator=n; denominator=1; } public Fraction(int n, int d) throws FractionException { if(d<0){ d*=-1; n*=-1; } else if(d==0) { throw new FractionException("denominator is zero!"); } numerator=n; denominator=d; reduction(); } public static int gcd(int x, int y){ int wk=1; x*=Integer.signum(x);//符号無しにする y*=Integer.signum(y); while(y != 0){ wk = x % y; x = y; y = wk; } return x; } public static Fraction compute(String exp) throws FractionException { // "( 3 + 5 ) * 7 - 2" のような文字列を計算する Stack
cstack = new Stack
(); //演算子スタック Stack
vstack = new Stack
(); //値スタック FractionParser parser = new FractionParser(exp); String token, op; Fraction x,y; while(parser.hasNext()){ token=parser.next(); switch(parser.status){ case PARENTHESES://カッコ //最初と最後の( )を取り除いて計算しスタックに積む vstack.push(compute(token.substring(1,token.length()-1))); break; case OPERATOR: //演算子 if (token.equals("*") || token.equals("/")){ if(cstack.empty()){ cstack.push(token); } else { op = cstack.peek(); if(op.equals("+") || op.equals("-")){ cstack.push(token); } else { y=vstack.pop();x=vstack.pop(); if(op.equals("*")){ vstack.push(x.multiply(y)); } else if(op.equals("/")){ vstack.push(x.divide(y)); } cstack.pop(); cstack.push(token); } } } else if (token.equals("+") || token.equals("-")){ if(cstack.empty()){ cstack.push(token); } else { op = cstack.peek(); y=vstack.pop();x=vstack.pop(); if(op.equals("+")){ vstack.push(x.add(y)); } else if(op.equals("-")){ vstack.push(x.subtract(y)); } else if(op.equals("*")){ vstack.push(x.multiply(y)); } else if(op.equals("/")){ vstack.push(x.divide(y)); } cstack.pop(); cstack.push(token); } } break; case NUMBER: //数字 vstack.push(new Fraction(Integer.parseInt(token))); break; } } while(!cstack.empty()){ op=cstack.pop(); y=vstack.pop();x=vstack.pop(); if(op.equals("+")){ vstack.push(x.add(y)); } else if(op.equals("-")){ vstack.push(x.subtract(y)); } else if(op.equals("*")){ vstack.push(x.multiply(y)); } else if(op.equals("/")){ vstack.push(x.divide(y)); } } return(vstack.pop()); } public Fraction clone() throws CloneNotSupportedException { return (Fraction)super.clone(); } private void reduction(){ int gcd = gcd(numerator, denominator); numerator/=gcd; denominator/=gcd; } public Fraction negate() throws FractionException { return(new Fraction(numerator*-1, denominator)); } public Fraction invert() throws FractionException { return(new Fraction(denominator, numerator)); } public Fraction add(Fraction x) throws FractionException { return(new Fraction( this.numerator * x.denominator + this.denominator * x.numerator, this.denominator * x.denominator)); } public Fraction add(int n) throws FractionException { return(new Fraction(numerator+n*denominator, denominator)); } public Fraction subtract(Fraction x) throws FractionException { return(new Fraction( this.numerator * x.denominator - this.denominator * x.numerator, this.denominator * x.denominator)); } public Fraction subtract(int n) throws FractionException { return(new Fraction(numerator-n*denominator, denominator)); } public Fraction multiply(Fraction x) throws FractionException { return(new Fraction( this.numerator * x.numerator, this.denominator * x.denominator)); } public Fraction multiply(int x) throws FractionException { return(new Fraction(numerator * x, denominator)); } public Fraction divide(Fraction x) throws FractionException { return(new Fraction( this.numerator * x.denominator, this.denominator * x.numerator)); } public Fraction divide(int x) throws FractionException { return(new Fraction(numerator, denominator * x)); } public boolean equals(Fraction x){ return (this.numerator==x.numerator && this.denominator==x.denominator); } public int compareTo(Fraction x){ return (this.numerator*x.denominator-this.denominator*x.numerator); } public String toString(){ return (denominator==1)? ""+numerator : ""+numerator+"/"+denominator; } public byte byteValue(){ byte ret=(byte)(numerator/denominator); return ret; } public double doubleValue(){ double ret=(double)numerator/denominator; return ret; } public float floatValue(){ float ret=(float)numerator/denominator; return ret; } public int intValue(){ return (numerator/denominator); } public long longValue(){ long ret=(long)numerator/denominator; return ret; } public short shortValue(){ short ret=(short)(numerator/denominator); return ret; } static class FractionParser { private String original; private String expression; private Pattern pnum = Pattern.compile("-?\\d+"); private Pattern pop = Pattern.compile("[-\\+\\*/]"); public State status = null; public FractionParser(String exp){ original=exp; expression = exp.replaceAll("\\s+",""); status=null; } public void reset(){ expression = original.replaceAll("\\s+",""); status=null; } public boolean hasNext() { return (expression.length()!=0); } public String next() throws FractionException { Matcher m; String token=""; if(expression.charAt(0)=='('){ StringReader sr = new StringReader(expression); int level=0; int pos=0; int ch; try{ while(-1!=(ch=sr.read())){ pos++; if(ch=='('){ level++; } else if(ch==')'){ level--; } if(level==0) break; } sr.close(); if(level!=0)//カッコの不整合 throw new FractionException("parse error:unmatch '( )'"); }catch(IOException e){}//文字列からのreadで例外は起こらんやろ? token=expression.substring(0,pos); expression=expression.substring(pos); status=State.PARENTHESES; return(token); } else if(status==null || status==State.OPERATOR){ m=pnum.matcher(expression); status=State.NUMBER; } else { m=pop.matcher(expression); status=State.OPERATOR; } if(m.lookingAt()){ token=expression.substring(m.start(),m.end()); expression=expression.substring(m.end()); return token; } else { status=null;//演算子が重複している時に起こる throw new FractionException("parse error:near "+expression); } } public String toString(){ return(expression); } } } class FractionException extends Exception { public FractionException() { super(); } public FractionException(String msg){ super(msg); } }