java算法计算一元一次方程是昨年10月写的了,最近想写写算法就把它整理出来了。

核心思想是将方程转化为:aX+b = cX+d 的形式再进行计算,转化的思想是根据符号的优先级一层一层的分割。分割规则是先把+号能分割完的分割完,再把-号能分割完的分割完,最后分割*/号,不能从括号里面分割。具体过程如下:

方程:-3-12+2*(-7+5x)=-3-4+3*(6x+9)+10*3-20-30,以左边为例:

先根据 + 号 分割,结果为:

左:-3-12                              +                             右: 2*(-7+5x)

左边只能根据 - 号分割,右边根据*号分割

左:左:-3    -    右:12         +                             右: 左:2         *       右:-7+5x

左边,右边都是 aX+b 形式直接计算,-3也是aX+b形式(a=0,b=-3)

左:-15                                  +                             右:-14+10x

最后左侧将转化为:10x-29

完整代码如下:

* Created by LL on 2016/10/13. public class yiyuanyicifangcheng { public static void main(String[] args) { String string= "-3-12+2*(-7+5x)=-3-4+3*(6x+9)+10*3-20-30"; double result = calculate(string); System.out.println( "计算结果:x = "+result); * 此类方法用于将字符串化为: aX+b 结构,结果返回a,b * @param str:需要计算的字符串 public static Result translate(String str) { str=deleteKH(str); char[] chars = str.toCharArray(); //先根据 + 号 将字符串分割完 for ( int i = 0, kuHaoNum = 0; i < chars.length; i++) { kuHaoNum = getBracketsNum(kuHaoNum,i,chars); if(kuHaoNum== 0&&( "+".equals(chars[i]+ ""))){ //括号里面不分割 String s01=str.substring( 0,i); String s02=str.substring(i+ 1, str.length()); Result result01=getResultFromString(s01); Result result02=getResultFromString(s02); Result result= new Result(); result.setA(result01.getA()+result02.getA()); result.setB(result01.getB()+result02.getB()); return result; //再根据 - 号 将字符串分割完 注意:- 号是从后往前分割 for ( int i=chars.length- 1,kuHaoNum= 0;i>= 0 ;i--) { kuHaoNum = getBracketsNum(kuHaoNum,i,chars); if(kuHaoNum== 0&&( "-".equals(chars[i]+ ""))){ //括号里面不分割 String s01=str.substring( 0,i); String s02=str.substring(i+ 1, str.length()); Result result01=getResultFromString(s01); Result result02=getResultFromString(s02); Result result= new Result(); result.setA(result01.getA()-result02.getA()); result.setB(result01.getB()-result02.getB()); return result; //最后根据 *,/ 号 将字符串分割 for( int i= 0,kuHaoNum= 0;i<chars.length;i++){ kuHaoNum = getBracketsNum(kuHaoNum,i,chars); if(kuHaoNum== 0&&( "*".equals(chars[i]+ "")|| "/".equals(chars[i]+ ""))){ //括号里面不分割 String s01=str.substring( 0, i); String fuhao=str.substring(i, i+ 1); String s02=str.substring(i+ 1, str.length()); Result result01=getResultFromString(s01); Result result02=getResultFromString(s02); Result result= new Result(); if(fuhao.equals( "*")){ //因为是一元一次方程 不会出现 (aX+b)*(aX+b)的情况 if(result01.getA()!= 0){ result.setA(result01.getA()*result02.getB()); result.setB(result01.getB()*result02.getB()); if(result02.getA()!= 0){ result.setA(result01.getB()*result02.getA()); result.setB(result01.getB()*result02.getB()); if(result01.getA()== 0&&result02.getA()== 0){ result.setA( 0.0); result.setB(result01.getB()*result02.getB()); } else if(fuhao.equals( "/")){ result.setA(result01.getA()/result02.getB()); result.setB(result01.getB()/result02.getB()); return result; return null; * 此类方法用于获取从起始位置到当前位置经历了几个括号 * @param num:括号数量 * @param index:字符数组的位置 * @param chars:字符数组 public static int getBracketsNum( int num, int index, char[] chars){ if( "(".equals(chars[index]+ "")){ num++; } else if( ")".equals(chars[index]+ "")){ num--; return num; * 此类方法用于将字符串转化为 aX+b 的形式 返回 Result * @param str:需要转化的字符串 public static Result getResultFromString(String str){ Result result = new Result(); if(str.equals( "")){ result.setA( 0.0); result.setB( 0.0); } else if(isRightString(str)){ String standString=getStandardFormatString(str); standString=deleteKH(standString); result.setA(Double.parseDouble(standString.substring( 0,standString.indexOf( "x")))); result.setB(Double.parseDouble(standString.substring(standString.indexOf( "x")+ 1,standString.length()))); } else if (isNum(str)){ result.setA( 0.0); result.setB(Double.parseDouble(str)); } else{ result=translate(str); return result; * 此类方法用于计算方程 * @param string:需要计算的方程 public static double calculate(String string){ String string01=string.substring( 0,string.indexOf( "=")); String string02=string.substring(string.indexOf( "=")+ 1,string.length()); Result result01=translate(string01); Result result02=translate(string02); System.out.println( "原方程为:"+string); System.out.println( "转化后的标准格式为:"+result01.getA()+ "x+("+result01.getB()+ ")="+result02.getA()+ "x+("+result02.getB()+ ")"); double a1=result01.getA(); double b1=result01.getB(); double a2=result02.getA(); double b2=result02.getB(); if(a1==a2&&b1!=b2){ System.out.println( "此方程无解"); } else if(a1==a2&&a1==b2){ System.out.println( "此方程有任意解"); } else if(a1!=a2){ return (b2-b1)/(a1-a2); return 0.0; * 此类方法用于判断字符串是否是数字 * @param str:需要判断的字符串 public static boolean isNum(String str){ boolean isNum = true; double d = Double.parseDouble(str); } catch (Exception e){ isNum = false; return isNum; * 此类方法用于判断字符串是否是类似于 aX+b 格式 * @param s:需要判断的字符串 public static boolean isRightString(String s){ char[] c=s.toCharArray(); int j= 0; for( int i= 0;i<c.length;i++){ if( "+".equals(c[i]+ "")|| "-".equals(c[i]+ "")){ if(s.contains( "x")&&j<= 1){ if(!s.contains( "(")){ return true; } else if(s.contains( "(")&&s.indexOf( "(")== 0){ return true; return false; * 此类方法用于将字符串转化为 aX+b 标准格式 * @param s:需要转化的字符串 public static String getStandardFormatString(String s){ char[] c=s.toCharArray(); int t= 0; StringBuffer s1= new StringBuffer(s); if(s.contains( "+")||s.contains( "-")){ for( int i= 0;i<c.length;i++){ if( "+".equals(c[i]+ "")|| "-".equals(c[i]+ "")){ t=i; //t 用于记住 +,-号的位置 break; if(s.indexOf( "x")<t){ return s; } else{ String s2=s.substring( 0,t); String s3=s.substring(t,s.length()); StringBuffer ss= new StringBuffer(s3); ss.append(s2); return ss.toString(); } else{ return s1.append( "+0").toString(); * 此类方法用于去掉字符串最外层的括号 * @param str:需要处理的字符串 public static String deleteKH(String str){ if(str.startsWith( "(")&&str.endsWith( ")")){ str = str.substring( 1, str.length() - 1); return str;