色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術(shù)文章
文章詳情頁

利用Java動(dòng)態(tài)編譯計(jì)算數(shù)學(xué)表達(dá)式

瀏覽:5日期:2024-06-16 17:46:54
內(nèi)容: 前幾天要做一個(gè)計(jì)算數(shù)學(xué)表達(dá)式的題目,本來計(jì)劃使用解析表達(dá)式的方法來解析各種數(shù)學(xué)表達(dá)式,然后再動(dòng)態(tài)計(jì)算表達(dá)式的值.后來考慮到這樣編程的任務(wù)很重,時(shí)間有限 后來在網(wǎng)上搜搜,看到使用動(dòng)態(tài)編譯并使用反射機(jī)制 ,這樣計(jì)算表達(dá)式的編程就容易多了.下面是我這次編程的例子, 請(qǐng)大家看看.01 /*02 * Created on 2006-3-803 * @author icerain 我的Blog: http://blog.matrix.org.cn/page/icess04 */05 06 public interface IOperator {07 String SIN = 'sin';08 String COS = 'cos';09 String TAN = 'tan';10 String ASIN = 'asin';11 String ACOS = 'acos';12 String ATAN = 'atan';13 String EXP = 'exp';14 String LOG = 'log';15 String POW = 'pow';16 String SQRT = 'sqrt';17 String FABS = 'fabs';18 String MINUS = 'minus';19 20 String J_SIN = 'Math.sin';21 String J_COS = 'Math.cos';22 String J_TAN = 'Math.tan';23 String J_ASIN = 'Math.asin';24 String J_ACOS = 'Math.acos';25 String J_ATAN = 'Math.atan';26 String J_EXP = 'Math.exp';27 String J_LOG = 'Math.log10';28 String J_POW = 'Math.pow';29 String J_SQRT = 'Math.sqrt';30 String J_FABS = 'Math.abs';31 32 } 定義一個(gè)接口, 用來轉(zhuǎn)換各種數(shù)學(xué)符號(hào)為Java類庫中的表達(dá)式.下面是用來計(jì)算的代碼.001 /*002 * Created on 2006-3-7003 * @author icerain 我的Blog: http://blog.matrix.org.cn/page/icess004 */005 //package hust.icess.simpson;006 007 008 import java.util.logging.Level;009 010 import java.io.*;011 import java.lang.reflect.Method;012 import java.util.Scanner;013 import java.util.logging.Logger;014 015 016 import com.sun.tools.javac.*;017 /**018 * 利用Simpson公式計(jì)算積分,在輸入被積公式時(shí)候請(qǐng)注意使用如下格式.019 * 1.只使用圓括號(hào)() , 沒有別的括號(hào)可以使用.如: 1/(1+sin(x))020 * 2.在輸入超越函數(shù)的時(shí)候,變量和數(shù)值用括號(hào)擴(kuò)起來 如:sin(x) 而不要寫為 sinx021 * 3.在兩個(gè)數(shù)或者變量相乘時(shí)候,不要省略乘號(hào)* 如:2*a 不要寫為 2a022 * 4.在寫冪運(yùn)算的時(shí)候,請(qǐng)使用如下格式: 023 * 利用動(dòng)態(tài)編譯來計(jì)算Simpson積分,使用該方法 編程相對(duì)簡(jiǎn)單,運(yùn)行效率有點(diǎn)慢.024 * @author icerain025 *026 */027 public class Simpson implements IOperator {028 /**029 * Logger for this class030 */031 private static final Logger logger = Logger.getLogger(Simpson.class032 .getName());033 034 private String expression = null;035 036 private String variable = null;037 038 private String[] variableValue = new String[3];039 040 // private static Main javac = new Main();041 042 /**主函數(shù) */043 public static void main(String[] args) throws Exception {044 Simpson sim = new Simpson();045 System.out.println('結(jié)果如下:');046 System.out.print(sim.getSimpsonValue());047 System.exit(0);048 049 }050 051 public Simpson() {052 logger.setLevel(Level.WARNING);053 init();054 }055 056 /** 初始化用戶輸入,為技術(shù)Simpson積分做準(zhǔn)備. */057 private void init() {058 Scanner scanner = new Scanner(System.in);059 System.out.println('請(qǐng)輸入函數(shù)表達(dá)式 如 1+sin(a) + cos(a)/a :');060 // String input = scanner.nextLine();061 //讀入被積函數(shù)的表達(dá)式062 expression = scanner.nextLine().trim().toLowerCase();063 System.out.println('請(qǐng)輸入變量字符 如 a :');064 //讀入變量字符065 variable = scanner.nextLine().trim().toLowerCase();066 067 //處理多元函數(shù) 目前不實(shí)現(xiàn)該功能068 // String[] tempVars = tempVar.split(' ');069 // for(int i = 0; i < tempVars.length; i ++) {070 // variable[i] = tempVars[i];071 // }072 073 System.out.println('請(qǐng)輸入積分區(qū)間和結(jié)點(diǎn)數(shù) 如 2 5.4 10 :');074 //讀取復(fù)合Simpson公式的積分參數(shù)075 String tempValue = scanner.nextLine().trim();076 String[] tempValues = tempValue.split(' ');077 for (int i = 0; i < tempValues.length; i++) {078 variableValue[i] = tempValues[i];079 }080 081 }082 083 /** 計(jì)算 Simpson積分的值*/084 public double getSimpsonValue() {085 //保存中間結(jié)果086 double value1 = 0;087 double value2 = 0;088 double tempValue = 0;089 int i = 0;090 // 解析輸入的積分參數(shù)值091 int n = Integer.parseInt(variableValue[2]);092 double a = Double.parseDouble(variableValue[0]);093 double b = Double.parseDouble(variableValue[1]);094 double h = (b - a) / n;095 //計(jì)算value1096 for (i = 0; i < n; i++) {097 tempValue = a + (i + 0.5) * h;098 String code = getSourceCode(expression, getVariable(), Double099 .toString(tempValue));100 try {101 value1 += run(compile(code));102 } catch (Exception e) {103 // TODO Auto-generated catch block104 e.printStackTrace();105 106 if (logger.isLoggable(Level.INFO)) {107 logger.info('something is wrong');108 }109 }110 }111 //計(jì)算value2112 for (i = 1; i < n; i++) {113 tempValue = a + i * h;114 String code = getSourceCode(expression, getVariable(), Double115 .toString(tempValue));116 try {117 value2 += run(compile(code));118 } catch (Exception e) {119 // TODO Auto-generated catch block120 e.printStackTrace();121 if (logger.isLoggable(Level.INFO)) {122 logger.info('something is wrong');123 }124 }125 }126 127 //計(jì)算f(a) f(b) 的函數(shù)值128 double valueA = getFunctionValue(a);129 double valueB = getFunctionValue(b);130 //計(jì)算Simpson公式的值131 double resultValue = (valueA + valueB + 4 * value1 + 2 * value2) * h / 6;132 133 return resultValue;134 }135 136 //計(jì)算F(a) 的值137 private double getFunctionValue(double varValue) {138 String code = getSourceCode(expression, getVariable(), Double139 .toString(varValue));140 double result = 0;141 try {142 result = run(compile(code));143 } catch (Exception e) {144 // TODO Auto-generated catch block145 e.printStackTrace();146 if (logger.isLoggable(Level.INFO)) {147 logger.info('something is wrong');148 }149 }150 return result;151 }152 153 /** 154 * 得到用戶輸入表達(dá)式轉(zhuǎn)換為Java中的可計(jì)算表達(dá)式的函數(shù)155 * @param ex 輸入的表達(dá)式 如: 1/(1 + sin(x)) 156 * @param var 表達(dá)式中的變量 如: x157 * @param value 變量的取值 如: 4.3158 * @return Java中可以直接計(jì)算的表達(dá)式 如: 1/(1 + Math.sin(x))159 */160 private String getSourceCode(String ex, String var, String value) {161 String expression = ex;162 //計(jì)算多個(gè)變量的函數(shù)的時(shí)候使用163 164 expression = expression.replaceAll(var, value);165 166 //處理數(shù)學(xué)符號(hào)167 if (expression.contains(SIN)) {168 expression = expression.replaceAll(SIN, J_SIN);169 } else if (expression.contains(COS)) {170 expression = expression.replaceAll(COS, J_COS);171 } else if (expression.contains(TAN)) {172 expression = expression.replaceAll(TAN, J_TAN);173 } else if (expression.contains(ASIN)) {174 expression = expression.replaceAll(ASIN, J_ASIN);175 } else if (expression.contains(ACOS)) {176 expression = expression.replaceAll(ACOS, J_ACOS);177 } else if (expression.contains(ATAN)) {178 expression = expression.replaceAll(ATAN, J_ATAN);179 } else if (expression.contains(EXP)) {180 expression = expression.replaceAll(EXP, J_EXP);181 } else if (expression.contains(LOG)) {182 expression = expression.replaceAll(LOG, J_LOG);183 } else if (expression.contains(POW)) {184 expression = expression.replaceAll(POW, J_POW);185 } else if (expression.contains(SQRT)) {186 expression = expression.replaceAll(SQRT, J_SQRT);187 } else if (expression.contains(FABS)) {188 expression = expression.replaceAll(FABS, J_FABS);189 }190 191 return expression;192 }193 194 /** 編譯JavaCode,返回java文件*/195 private synchronized File compile(String code) throws Exception {196 File file;197 // 創(chuàng)建一個(gè)臨時(shí)java源文件198 file = File.createTempFile('JavaRuntime', '.java', new File(System199 .getProperty('user.dir')));200 if (logger.isLoggable(Level.INFO)) {201 logger.info(System.getProperty('user.dir'));202 }203 // 當(dāng)Jvm 退出時(shí) 刪除該文件204 file.deleteOnExit();205 // 得到文件名和類名206 String filename = file.getName();207 if (logger.isLoggable(Level.INFO)) {208 logger.info('FileName: ' + filename);209 }210 String classname = getClassName(filename);211 // 將代碼輸出到源代碼文件中212 PrintWriter out = new PrintWriter(new FileOutputStream(file));213 // 動(dòng)態(tài)構(gòu)造一個(gè)類,用于計(jì)算214 out.write('public class ' + classname + '{'215 + 'public static double main1(String[] args)' + '{');216 out.write('double result = ' + code + ';');217 //用于調(diào)試218 //out.write('System.out.println(result);');219 out.write('return new Double(result);');220 out.write('}}');221 //關(guān)閉文件流222 out.flush();223 out.close();224 //設(shè)置編譯參數(shù)225 String[] args = new String[] { '-d', System.getProperty('user.dir'),226 filename };227 //調(diào)試228 if (logger.isLoggable(Level.INFO)) {229 logger.info('編譯參數(shù): ' + args[0]);230 }231 //Process process = Runtime.getRuntime().exec('javac ' + filename);232 int status = Main.compile(args);233 //輸出運(yùn)行的狀態(tài)碼.234 // 狀態(tài)參數(shù)與對(duì)應(yīng)值 235 // EXIT_OK 0 236 // EXIT_ERROR 1 237 // EXIT_CMDERR 2 238 // EXIT_SYSERR 3 239 // EXIT_ABNORMAL 4240 if (logger.isLoggable(Level.INFO)) {241 logger.info('Compile Status: ' + status);242 }243 //System.out.println(process.getOutputStream().toString());244 return file;245 }246 247 /**248 * 運(yùn)行程序 如果出現(xiàn)Exception 則不做處理 拋出!249 * @param file 運(yùn)行的文件名250 * @return 得到的Simpson積分公式的結(jié)果251 * @throws Exception 拋出Exception 不作處理252 */253 private synchronized double run(File file) throws Exception {254 String filename = file.getName();255 String classname = getClassName(filename);256 Double tempResult = null;257 // System.out.println('class Name: ' +classname);258 //當(dāng)Jvm 退出時(shí)候 刪除生成的臨時(shí)文件259 new File(file.getParent(), classname + '.class').deleteOnExit();260 try {261 Class cls = Class.forName(classname);262 //System.out.println('run........');263 // 映射main1方法264 Method calculate = cls265 .getMethod('main1', new Class[] { String[].class });266 //執(zhí)行計(jì)算方法 得到計(jì)算的結(jié)果267 tempResult = (Double) calculate.invoke(null,268 new Object[] { new String[0] });269 } catch (SecurityException se) {270 System.out.println('something is wrong !!!!');271 System.out.println('請(qǐng)重新運(yùn)行一遍');272 }273 //返回值274 return tempResult.doubleValue();275 }276 277 /** 調(diào)試函數(shù)*/278 // private void debug(String msg) {279 // System.err.println(msg);280 // }281 282 /** 得到類的名字 */283 private String getClassName(String filename) {284 return filename.substring(0, filename.length() - 5);285 }286 287 288 //getter and setter289 public String getExpression() {290 return expression;291 }292 293 public void setExpression(String expression) {294 this.expression = expression;295 }296 297 public String getVariable() {298 return variable;299 }300 301 public void setVariable(String variable) {302 this.variable = variable;303 }304 305 public String[] getVariableValue() {306 return variableValue;307 }308 309 public void setVariableValue(String[] variableValue) {310 this.variableValue = variableValue;311 }312 } 這樣就可以用來計(jì)算了.下面編寫一個(gè).bat文件來運(yùn)行改程序.(在這里沒有打包為.jar文件)@echo 注意:@echo ***********************************************************@echo * 利用Simpson公式計(jì)算積分,在輸入被積公式時(shí)候請(qǐng)注意使用 ***@echo * 如下格式. ***@echo * 1.只使用圓括號(hào)() , 沒有別的括號(hào)可以使用.如: ***@echo * 1/(1+sin(x)) ***@echo * 2.在輸入超越函數(shù)的時(shí)候,變量和數(shù)值用括號(hào)擴(kuò)起來 如: ***@echo * sin(x) 而不要寫為 sinx ***@echo * 3.在兩個(gè)數(shù)或者變量相乘時(shí)候,不要省略乘號(hào)* 如: ***@echo * 2*a 不要寫為 2a ***@echo * 4.在寫冪運(yùn)算的時(shí)候,請(qǐng)使用如下格式: ***@echo * pow(x,y) 代表x的y次冪 不要使用其他符號(hào) ***@echo * 5.絕對(duì)值請(qǐng)用如下符號(hào)表示: ***@echo * fabs(x) 代表x的絕對(duì)值 ***@echo * 6.指數(shù)函數(shù)請(qǐng)用exp表示 如:exp(x) ***@echo * 7.對(duì)數(shù)函數(shù)請(qǐng)用log(x)表示, 該處對(duì)數(shù)是指底為10的對(duì)數(shù), ***@echo * 計(jì)算不是以10為底的對(duì)數(shù)時(shí)候請(qǐng)轉(zhuǎn)換為10為底的對(duì)數(shù) ***@echo * 8.變量字符請(qǐng)不要與函數(shù)中的其他字符重合,如 如果使用了 ***@echo * sin 函數(shù)請(qǐng) 不要用 s i 或者n做為變量,否則在解析 ***@echo * 表達(dá)式時(shí)候 會(huì)出錯(cuò) ^_^@echo *********************************************************** @Rem 在編譯源文件時(shí)候 要使用下面的命令 把rem 刪除即可 注意 由于文件中用到了tools.jar中@rem 的命令 所有在編譯的時(shí)候 用適當(dāng)?shù)腸lasspath 替換下面的 tools.jar的路徑 運(yùn)行的時(shí)候一樣@rem javac -classpath '.;D:Program FilesJavajdk1.5.0_03libtools.jar;%CLASSPATH%' Simpson.java %1@rem 注意更改此處的tools.jar的路徑 為你當(dāng)前系統(tǒng)的正確路徑@java -cp '.;D:Program FilesJavajdk1.5.0_03libtools.jar' Simpson@Pause  這樣就可以了.說明:使用該方法來計(jì)算本程序,由于要多次動(dòng)態(tài)產(chǎn)生計(jì)算源代碼,并且編譯 在性能上會(huì)有很大損失. 要是在項(xiàng)目中不經(jīng)常計(jì)算表達(dá)式 使用該方法可以減輕編程的負(fù)擔(dān).要是象上面那樣 要多次計(jì)算的話,使用該方法是很值得考慮的. Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd 前幾天要做一個(gè)計(jì)算數(shù)學(xué)表達(dá)式的題目,本來計(jì)劃使用解析表達(dá)式的方法來解析各種數(shù)學(xué)表達(dá)式,然后再動(dòng)態(tài)計(jì)算表達(dá)式的值.后來考慮到這樣編程的任務(wù)很重,時(shí)間有限 后來在網(wǎng)上搜搜,看到使用動(dòng)態(tài)編譯并使用反射機(jī)制 ,這樣計(jì)算表達(dá)式的編程就容易多了.下面是我這次編程的例子, 請(qǐng)大家看看.01 /*02 * Created on 2006-3-8
標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 久久九九精品一区二区 | 欧美一区二区三区在线 | 麻豆传媒一区 | 久久久久国产免费 | 男女乱配视频免费观看 | 日本国产最新一区二区三区 | 欧美曰批人成在线观看 | 韩日精品| 一区二区国产在线播放 | 全免费a级毛片免费毛视频 全午夜免费一级毛片 | 男女男在线精品网站免费观看 | 国产成人a大片大片在线播放 | 亚洲精品国产一区二区三 | 三级午夜三级三点在看 | 窝窝人体色| 国产亚洲精品美女一区二区 | 99re热在线视频 | 国产成人午夜性视频影院 | 久久有这有精品在线观看 | 中文字幕免费在线视频 | 国产美女视频黄a视频全免费网站 | 狠狠色噜狠狠狠狠色综合久 | 日本人在线看片 | 欧美精品hdxxxxx | 国产精品免费久久久免费 | 一区二区精品视频 | 欧美激情久久久久久久大片 | a级国产乱理伦片在线 | 永久免费不卡在线观看黄网站 | 热99re久久精品2久久久 | 国产一区影视 | 免费一级片视频 | 亚洲欧美日韩久久精品第一区 | 特黄毛片 | 综合久久久久久 | 国产a级精品特黄毛片 | 国产男女免费视频 | 久久看视频| a中文字幕1区 | 末满18以下勿进色禁网站 | 亚洲一区二区精品视频 |