?? izracunavanje.java
字號:
package w3eval;import java.util.Vector;import java.text.DecimalFormat;import java.math.BigDecimal;final public class Izracunavanje { // vraca poziciju prve zatvorene zagrade u vektoru "tokeni" // ako je ne nade vraca 0 // provjera : da public static int pozicija_prve_zatvorene_zagrade( Vector tokeni ) { Token t; for ( int i=0; i<tokeni.size(); i++ ) { t=(Token)tokeni.elementAt( i ); if ( t.oznaka==')' ) return i; } return 0; } // vraca poziciju otvorene zagrade koja odgovara pronadenoj zatvorenoj zagradi // poziv ima smisla samo ako funkcija "pozicija_prve_zatvorene_zagrade" nade zatvorenu zagradu // provjera : da public static int pozicija_otvorene_zagrade( Vector tokeni, int pozicija_zatvorene_zagrade ) { int i; Token t; i=pozicija_zatvorene_zagrade-2; while ( i>=0 ) { t=(Token)tokeni.elementAt( i ); if ( t.oznaka=='(' ) { return i; } i--; } return 0; } // vraca raspon zagrada koji ce se izracunati // otvorena i zatvorena zagrada ulaze u raspon // ako nema zagrada vraca null // provjera : da static public Raspon raspon_zagrada( Vector tokeni ) { int poz_otvor_zagrade; int poz_zatvor_zagrade; Raspon raspon = null; poz_zatvor_zagrade=pozicija_prve_zatvorene_zagrade( tokeni ); if ( poz_zatvor_zagrade!=0 ) { poz_otvor_zagrade=pozicija_otvorene_zagrade( tokeni, poz_zatvor_zagrade ); raspon = new Raspon( poz_otvor_zagrade, poz_zatvor_zagrade ); } return raspon; } // iz dijelova koji se nalaze u vektoru formira string // provjera : da public static String spoj_tokena( Vector tokeni ) { String izraz=new String(); Token t; for ( int i=0; i<tokeni.size(); i++ ) { t=(Token)tokeni.elementAt( i ); if ( t.oznaka=='D' ) { double broj=((Double)t.token).doubleValue(); izraz=izraz + formatirani_broj( broj ); } else izraz=izraz + t.token; if ( izraz.endsWith( ".0" ) ) izraz=izraz.substring( 0, izraz.length()-2 ); izraz=izraz + " "; } return izraz; } public static String formatirani_broj( double d ) { if ( 1E-15<Math.abs(d) && Math.abs(d)<1E+15 ) { DecimalFormat df = new DecimalFormat( "#.###############################" ); return df.format( d ).replace( ',', '.' ); } else return String.valueOf( d ); } // vraca poziciju unutar raspona zagrada gdje se nalazi operator s najvisim prioritetom // ako unutar raspona zagrada nema niti jednog operatora vraca 0 // provjera : da public static int pozicija_operatora( Vector tokeni, Raspon raspon_zagrada ) { byte max_prioritet=Byte.MAX_VALUE; int max_pozicija=0; byte prioritet; String operator; Token t; for ( int i=raspon_zagrada.pocetak+2; i<=raspon_zagrada.kraj-2; i++ ) { t=(Token)tokeni.elementAt( i ); if ( t.oznaka!='P' ) continue; prioritet=((Operator)t.token).prioritet; operator=((Operator)t.token).operator; if ( prioritet < max_prioritet || ( operator.equals("^") || operator.equals("**") ) && prioritet == max_prioritet ) { max_prioritet=prioritet; max_pozicija=i; } } return max_pozicija; } // provjera : da public static double rezultat_operacije( double broj1, double broj2, String op ) { double rezultat=0; if ( op.equals( "^" ) || op.equals( "**" ) ) // rezultat=Math.pow( broj1, broj2 ); rezultat=Matematika.potenciranje( broj1, broj2 ); else if ( op.equals( "*" ) ) // rezultat=broj1*broj2; rezultat=Matematika.mnozenje( broj1, broj2 ); else if ( op.equals( "/" ) ) // rezultat=broj1/broj2; rezultat=Matematika.dijeljenje( broj1, broj2 ); else if ( op.equals( "mod" ) ) rezultat=Math.IEEEremainder( broj1, broj2 ); else if ( op.equals( "%" ) ) rezultat=broj1%broj2; else if ( op.equals( "+" ) ) // rezultat=broj1+broj2; rezultat=Matematika.zbrajanje( broj1, broj2 ); else if ( op.equals( "-" ) ) // rezultat=broj1-broj2; rezultat=Matematika.oduzimanje( broj1, broj2 ); else if ( op.equals( "<<" ) ) rezultat=(long)broj1<<(long)broj2; else if ( op.equals( ">>" ) ) rezultat=(long)broj1>>(long)broj2; else if ( op.equals( ">>>" ) ) rezultat=(long)broj1>>>(long)broj2; else if ( op.equals( "<" ) ) rezultat=broj1<broj2 ? 1:0; else if ( op.equals( ">" ) ) rezultat=broj1>broj2 ? 1:0; else if ( op.equals( "<=" ) ) rezultat=broj1<=broj2 ? 1:0; else if ( op.equals( ">=" ) ) rezultat=broj1>=broj2 ? 1:0; else if ( op.equals( "==" ) ) rezultat=broj1==broj2 ? 1:0; else if ( op.equals( "!=" ) || op.equals( "<>" ) ) rezultat=broj1!=broj2 ? 1:0; else if ( op.equals( "and" ) ) rezultat=(long)broj1 & (long)broj2; else if ( op.equals( "xor" ) ) rezultat=(long)broj1 ^ (long)broj2; else if ( op.equals( "or" ) ) rezultat=(long)broj1 | (long)broj2; else if ( op.equals( "&&" ) ) rezultat=(broj1!=0 && broj2!=0) ? 1:0; else if ( op.equals( "||" ) ) rezultat=(broj1!=0 || broj2!=0) ? 1:0; return rezultat; } // provjera : da public static double vrijednost_operanda( Token t ) { if ( t.oznaka=='V' ) return ((Varijabla)t.token).vrijednost; else if ( t.oznaka=='D' ) return ((Double)t.token).doubleValue(); else if ( t.oznaka=='H' ) return Matematika.baza_broj( ((String)t.token).substring(2), 16 ); else if ( t.oznaka=='O' ) return Matematika.baza_broj( ((String)t.token).substring(2), 8 ); else if ( t.oznaka=='B' ) return Matematika.baza_broj( ((String)t.token).substring(2), 2 ); return 0; } // vrsi jedan korak racunanja izraza i u skladu s tim mijenja vektor tokena // ako je izraz izracunat do kraja vraca FALSE, ako nije TRUE. // provjera : da public static boolean korak_izracunavanja( Vector tokeni ) { boolean ima_zagrada=true; Token t; Raspon rang=raspon_zagrada( tokeni ); // ako nema zagrada, rang obuhvaca cijeli izraz if ( rang==null ) { // rang ukljucuje virtualne zagrade rang=new Raspon( -1, tokeni.size() ); ima_zagrada=false; } int poz_max_op=pozicija_operatora( tokeni, rang ); // ako nema operatora if ( poz_max_op==0 ) { // ako nema zagrada, izraz je izracunat do kraja if ( !ima_zagrada ) { return false; } // funkcijska zagrada else { double rezultat; rezultat=rezultat_funkcije( tokeni, rang.pocetak-1 ); izbaci_tokene( tokeni, rang.pocetak-1 ); t = new Token ( new Double(rezultat), 'D', 0, 0 ); tokeni.setElementAt( t, rang.pocetak-1 ); izbacivanje_zagrada( tokeni, rang.pocetak-1 ); return true; } } double operand1, operand2; // odredivanje 1. operanda t=(Token)tokeni.elementAt( poz_max_op-1 ); operand1=vrijednost_operanda( t ); // odredivanje 2. operanda t=(Token)tokeni.elementAt( poz_max_op+1 ); operand2=vrijednost_operanda( t ); // odredivanje operatora t=(Token)tokeni.elementAt( poz_max_op ); String op=((Operator)t.token).operator; double rezultat=rezultat_operacije( operand1, operand2, op ); tokeni.removeElementAt( poz_max_op+1 ); tokeni.removeElementAt( poz_max_op ); t = new Token ( new Double(rezultat), 'D', 0, 0 ); tokeni.setElementAt( t, poz_max_op-1 ); izbacivanje_zagrada( tokeni, poz_max_op-1 ); return true; } // izbacuje tokene iz vektora nakon sto se izracuna funkcija // izbacuje se otvorena zagrada, argumenti, zarezi i zatvorena zagrada // na mjesto funkcije umetnut ce se kasnije rezultat funkcije // provjera : da private static void izbaci_tokene( Vector tokeni, int pozicija_funkcije ) { while ( ((Token)tokeni.elementAt( pozicija_funkcije )).oznaka!=')' ) { tokeni.removeElementAt( pozicija_funkcije ); } } public static void izbacivanje_visestrukih_zagrada( Vector tokeni ) { Vector pomocni=new Vector( tokeni ); Raspon r; while ( (r=raspon_zagrada( pomocni ))!=null ) { if ( r.pocetak!=0 && r.kraj!=pomocni.size()-1 && ((Token)pomocni.elementAt( r.pocetak-1 )).oznaka=='(' && ((Token)pomocni.elementAt( r.kraj+1 )).oznaka==')' ) { pomocni.removeElementAt( r.kraj+1 ); pomocni.removeElementAt( r.pocetak-1 ); tokeni.removeElementAt( r.kraj+1 ); tokeni.removeElementAt( r.pocetak-1 ); } else { // izbacivanje vanjskih zagrada if ( r.pocetak==0 && r.kraj==tokeni.size()-1 ) { tokeni.removeElementAt( r.kraj ); tokeni.removeElementAt( r.pocetak ); } else { // dummy tokeni na mjestu zagrada pomocni.setElementAt( new Token(null,(char)0,0,0), r.kraj ); pomocni.setElementAt( new Token(null,(char)0,0,0), r.pocetak ); } } } return; } private static void izbacivanje_zagrada( Vector tokeni, int poz )
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -