Android画曲線の文字列演算


最近カーブを描くツールを作りたいのですが、入力式(y=3*xなど)に基づいてカーブを描きます.まず、String expression=「1-(3*(5-3)+4/2)-3*cos(PI-PI/2)」などの文字列式を演算して評価する方法が問題になります.どうやって計算しますか?
観察によると、各括弧()内は小さな式で、まず最小括弧内の式値を算出しなければ、大きな括弧内の式値を演算することができず、それから最大括弧の式を演算することができない.最後に式全体を演算することができます.これは再帰ではありませんか.再帰を飛び出す条件は、サブ式に括弧がないことです. 
直接コードをつけましょう.
 
/**
 *    
 * @author Saber
 *
 */
public class Calculator {

	//   
	private static  enum Operator{
		add,sub,mutip,div;		
		 public static Operator getOperator(String operator){
			if(operator.equals("+")){
				return add;
			}else
			if(operator.equals("-")){
				return sub;
			}else
			if(operator.equals("*")){
				return mutip;
			}else
			if(operator.equals("/")){
				return mutip;
			}
			return null;
		}
		
	}
	//  
	private final String[] functions={"cos","sin"};
	//     
	private final String[] params={"x"};
	
	
	//    
	public static float calculate(String expression){
		String  noBracketExp="";//       
		String  subExp="";//        
		for(int i=0;i<expression.length();i++){
			String c=String.valueOf(expression.charAt(i));
			if("(".equals(c)){//       
				int bracket=0;
				for(int j=i+1;j<expression.length();j++){
					i++;
					c=String.valueOf(expression.charAt(j));
					if(c.equals("("))bracket++;else if(c.equals(")")) bracket--;
					if(bracket==-1)break;
					subExp+=c;
				}
				noBracketExp+=calculate(subExp);
				subExp="";
			}else noBracketExp+=c;
		}
		
		return szys(noBracketExp);
	}
		
	//        
	private static boolean isMutipOrDivideOperator(String operator){
		return Operator.getOperator(operator)==Operator.mutip||Operator.getOperator(operator)==Operator.div;
	}
		
	//      ,          
	private static float szys(String expression){
		expression=expression.replaceAll("\\-", "+-");
		String[] exps=expression.split("\\+");//        
		float result=0;
		for(String exp:exps){
			result+=multipAndDivide(exp);
		}
		
		return result;
	}
	
	//    
	private static float multipAndDivide(String exp){
		exp+="*1";//          ,         ,     。
		String p1="";
		String p2="";
		String operator="";
		for(int i=0;i<exp.length();i++){
			String s=String.valueOf(exp.charAt(i));
			if(isMutipOrDivideOperator(s)){//     
				operator=s;
				if(operator.length()>0&&p1.length()>0&&p2.length()>0){
					p1=szys(Float.valueOf(p1),operator,Float.valueOf(p2))+"";
					p2="";
				}
			}else if(operator.length()==0){
				p1+=s;
			}else{
				p2+=s;
			}
		}
		
		return Float.valueOf(p1);
	}
	
	//         
	private static float szys(float p1,String operator,float p2){
		if(operator.equals("+")){
			return p1+p2;
		}else if(operator.equals("-")){
			return p1-p2;
		}else if(operator.equals("*")){
			return p1*p2;
		}else if(operator.equals("/")){
			if(p2==0)return 0;else return p1/p2;
		}else return 0;
	}
	
	
	public static void main(String[] args){
		System.out.println(szys(10,"+",10));
		System.out.println(multipAndDivide("-3*3"));
		System.out.println(szys("10-2*2/2+4*2/2"));
		System.out.println(calculate("10-2*(5*2-2*(4-2)+4)+2"));
	}

	
	
}

 
 
以上は関数計算に関与せず,処理関数も簡単で,括弧の前の文字列が関数であるか否かを判断するだけで,もしそうであれば計算に組み込む.