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"));
}
}
以上は関数計算に関与せず,処理関数も簡単で,括弧の前の文字列が関数であるか否かを判断するだけで,もしそうであれば計算に組み込む.