zoukankan      html  css  js  c++  java
  • java算法计算一元一次方程

    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;
            try{
                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]+"")){
                    j++;
                }
            }
            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;
        }
    
        /**
         * 此类定义了  aX+b 结构中的 a和b
         * 注意 这里的a,b可以为负,即aX-b也属于这种结构
         */
        public static class Result{
            double a;
            double b;
            public Result(){
            }
            public Result(double a,double b) {
                this.a=a;
                this.b=b;
            }
            public double getA() {
                return a;
            }
            public double getB() {
                return b;
            }
            public void setA(double a) {
                this.a = a;
            }
            public void setB(double b) {
                this.b = b;
            }
            @Override
            public String toString() {
                return "Result{" +
                        "a=" + a +
                        ", b=" + b +
                        '}';
            }
        }
    }

    运行结果:

    这里写图片描述

  • 相关阅读:
    vsftpd用户登陆目录
    Linux下能否用用apache运行ASP.NET的WebService
    rose软件下载(Rational Rose 2003 Enterprise Edition)
    linux删除目录
    2013314 生活日记
    ubuntu12.10安装GTK+
    SqlServer 基础知识数据检索、查询排序
    获取时间段:本周、本月、本年
    二、自定义控件之RadioButtonList
    ext.net 开发学习之FileUploadField与Image (四)
  • 原文地址:https://www.cnblogs.com/yuchsheng/p/14134910.html
Copyright © 2011-2022 走看看