Expression derivation code based on java (including expression derivation and expression simplification)

This code is an error demonstration. It only implements the function but the structure and logic are a bit messy. There are still some code reuses that have not been checked. Due to the limited time and rush, this code supports constant functions, exponential functions, trigonometric functions and their combinations. Derivation of the expression below

For example, 5* sin(x) **4* sin(x) + 4*x--2, functions can be nested and the four arithmetic operations of function derivation can be realized.

The basic functions of this program have been implemented. If you need comments, please comment below, and I will update them when I see them.

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Qiudao {<!-- -->

    public String miQiu(String base, int zhi){<!-- -->
        // derivative
        int newzhi = zhi - 1;
        int xi = zhi;
        String derivative;
        if(newzhi == 1)derivative = xi + "*" + base;
        else derivative = xi + "*" + base + "**" + newzhi;

        // Return the result of derivation
        return derivative;
    }

    public String SanjQiu(String san, String jidi){<!-- -->
        if (san.equals("sin")) {<!-- -->
            return "cos(" + jidi + ")";
        }
        // If the expression is a cosine function, the derivative is a negative sine function
        else {<!-- -->
            return "-sin(" + jidi + ")";
        }
    }

    public String chenQiu(String op1, String op2, String dfdx1, String dfdx2){<!-- -->
        // Combine the two derivatives according to the multiplication rule
        String xi1 = chen(op1, dfdx2);
        String xi2 = chen(op2, dfdx1);
        String result = complexPlus(xi1, xi2);
        if(result.split("[ + ]").length!= 1){<!-- -->
            return "(" + result + ")";
        }
        else return result;
    }

    public String plusQiu(String c){<!-- -->
        String[] factors = c. split("\ + ");
        // Find the derivatives of two simple functions separately
        String dfdx1 = complexQiu(factors[0]);
        String dfdx2 = complexQiu(factors[1]);
        // Combine the two derivatives according to the multiplication rule
        String result = Plus(dfdx1, dfdx2);
        return result;
    }

    public ArrayList<String> plusSplit(String s){<!-- -->
        ArrayList<String> result = new ArrayList<>();
        s = s.replaceAll("\s", "");
        String[] parts = s.split("(?<=[ + -]|\s)|(?<=\*|\s)|(?<=[( )]|\s)|(<=[()])");
        ArrayList<String> format = new ArrayList<>();
        for (int i = 0; i < parts. length; i ++ ) {<!-- -->
            if(parts[i].length() >1 & amp; & amp;(parts[i].endsWith("*")||parts[i].endsWith(" + ")||parts [i].endsWith("-")||parts[i].endsWith("(")||parts[i].endsWith(")"))){<!-- - ->
                format.add(parts[i].substring(0, parts[i].length() - 1));
                format.add("" + parts[i].charAt(parts[i].length()-1));
            }else if(parts[i].equals("*") & amp; & amp;format.get(format.size()-1).equals("*")){<!-- -->
                format.set(format.size()-1, "**");
            }
            else{<!-- -->
                format. add(parts[i]);
            }
        }
        String index = "";
        if(format.get(0).equals("(")) {<!-- -->
            format. remove(0);
            format. remove(format. size()-1);
        }
        for(int i = 0;i<format. size();i ++ ){<!-- -->

            if(format.get(i).equals(" + ")) {<!-- -->
                result. add(index);
                index = "";
            }else{<!-- -->
                index + = format. get(i);
            }
        }
        result. add(index);
        return result;
    }

    public ArrayList<String> MultiSplit(String s){<!-- -->
        ArrayList<String> result = new ArrayList<>();
        s = s.replaceAll("\s", "");
        String[] parts = s.split("(?<=[ + -]|\s)|(?<=\*|\s)|(?<=[( )]|\s)|(<=[()])");
        ArrayList<String> format = new ArrayList<>();
        for (int i = 0; i < parts. length; i ++ ) {<!-- -->
            if(parts[i].length() >1 & amp; & amp;(parts[i].endsWith("*")||parts[i].endsWith(" + ")||parts [i].endsWith("-")||parts[i].endsWith("(")||parts[i].endsWith(")"))){<!-- - ->
                format.add(parts[i].substring(0, parts[i].length() - 1));
                format.add("" + parts[i].charAt(parts[i].length()-1));
            }else if(parts[i].equals("*") & amp; & amp;format.get(format.size()-1).equals("*")){<!-- -->
                format.set(format.size()-1, "**");
            }
            else{<!-- -->
                format. add(parts[i]);
            }
        }
        String index = "";
        for(int i = 0;i<format. size();i ++ ){<!-- -->
            if(format.get(i).equals("*") & amp; & amp;!format.get(i + 1).equals("*")) {<!-- -->
                result. add(index);
                index = "";
            }
            else{<!-- -->
                index + = format. get(i);
            }
        }
        result. add(index);
        return result;
    }

    public String chen(String a, String b){<!-- -->
        if(a.equals("0")||b.equals("0"))return "0";
        else if(a.equals("1")) return b;
        else if(b. equals("1")) return a;
        else if(a.equals("-1"))return "-" + b;
        else if(b.equals("-1"))return "-" + a;
        else if(b.charAt(0) == '-' & amp; & amp;a.charAt(0)!= '-') return "-" + a + "*" + b. substring(1, b. length());
        else if(b.charAt(0) == '-' & amp; & amp;a.charAt(0)=='-') return a + "*" + b.substring(1 , b. length());
        else if(b.charAt(0) == '('){<!-- -->
            String result = "";
            ArrayList<String> splits = plusSplit(b. substring(1, b. length()-1));
            for(int i = 0; i< splits. size();i ++ ){<!-- -->
                result + = a + "*" + splits.get(i) + " + ";
            }
            return result.substring(0, result.length()-1);
        }else if(a.charAt(0) == '('){<!-- -->
            String result = "";
            ArrayList<String> splits = plusSplit(a. substring(1, a. length()-1));
            for(int i = 0; i< splits. size();i ++ ){<!-- -->
                result + = b + "*" + splits.get(i) + " + ";
            }
            return result.substring(0, result.length()-1);
        }else if(a.charAt(0) == '(' & amp; & amp; b.charAt(0) == '('){<!-- -->
            String result = "";
            ArrayList<String> split1 = plusSplit(a. substring(1, a. length()-1));
            ArrayList<String> split2 = plusSplit(b. substring(1, b. length()-1));
            for(int i = 0; i< split1. size();i ++ ){<!-- -->
                for(int j = 0; j<split2. size();j ++ ){<!-- -->
                    result + = split1.get(i) + "*" + split2.get(j);
                }
                result + = " + ";
            }
            return result.substring(0, result.length()-1);
        }
            return a + "*" + b;
    }

    public String Plus(String a, String b){<!-- -->

        if(a.equals("0")||a.equals("")) return b;
        else if(b.equals("0")||b.equals("")) return a;
        else if(a.matches("\d + ") & amp; & amp;b.matches("\\d + ")){<!-- -->
            int c = Integer.parseInt(a) + Integer.parseInt(b);
            return Integer.toString(c);
        }
        else return a + " + " + b;
    }


    public String complexPlus(String a, String b){<!-- -->
        String result = "";
        int xi = 0;
        ArrayList<String> asplit = plusSplit(a);
        ArrayList<String> bsplit = plusSplit(b);
        ArrayList<String> res = new ArrayList<>();

        for(int i = 0; i < asplit. size(); i ++ ){<!-- -->
            if(asplit.get(i).matches("\d + ")){<!-- -->
                xi + = Integer. parseInt(asplit. get(i));
            }else{<!-- -->
                res.add(asplit.get(i));
            }
        }
        for(int j = 0; j< bsplit. size(); j ++ ){<!-- -->
            if(bsplit.get(j).matches("\d + ")){<!-- -->
                xi + = Integer. parseInt(bsplit. get(j));
            }else{<!-- -->
                res.add(bsplit.get(j));
            }
        }

        result = Integer.toString(xi);
        for(int i = 0; i<res. size();i ++ ){<!-- -->
            result = Plus(result, res. get(i));
        }

        return result;
    }

    public String jian(String a, String b){<!-- -->
        if(a.equals("0")) return "-" + b;
        else if(b. equals("0")) return a;
        else if(a.matches("\d + ") & amp; & amp;b.matches("\\d + ")){<!-- -->
            int c = Integer.parseInt(a)-Integer.parseInt(b);
            return Integer.toString(c);
        }
        else return a + "-" + b;
    }

    public String complexQiu(String s) {<!-- -->
        if(s.charAt(0) == '(') s = s.substring(1, s.length()-1);
        Stack<String> biaoda = new Stack<>();
        Stack<String> operators = new Stack<>();
        s = s.replaceAll("\s", "");
        String[] parts = s.split("(?<=[ + -]|\s)|(?<=\*|\s)|(?<=[( )]|\s)|(<=[()])");
        ArrayList<String> format = new ArrayList<>();
        for (int i = 0; i < parts. length; i ++ ) {<!-- -->
            if(parts[i].length() >1 & amp; & amp;(parts[i].endsWith("*")||parts[i].endsWith(" + ")||parts [i].endsWith("-")||parts[i].endsWith("(")||parts[i].endsWith(")"))){<!-- - ->
                format.add(parts[i].substring(0, parts[i].length() - 1));
                format.add("" + parts[i].charAt(parts[i].length()-1));
            }else if(parts[i].equals("*") & amp; & amp;format.get(format.size()-1).equals("*")){<!-- -->
                format.set(format.size()-1, "**");
            }
            else{<!-- -->
                format. add(parts[i]);
            }
        }

        for (int i = 0; i < format. size(); i ++ ) {<!-- -->
            if(i == 0 & amp; & amp; ((format.get(i).equals(" + ")||format.get(i).equals("-")) & amp; &format.get(i + 1).matches("\d + "))){<!-- -->
                biaoda.push("0");
                if(format.get(i).equals(" + ")) biaoda.push(format.get(i + 1));
                else biaoda. push(format. get(i) + format. get(i + 1));
                i + + ;
            }
            else if(format.get(i).matches("\d + ")){<!-- -->
                biaoda.push("0");
                biaoda.push(format.get(i));
            }
            else if((i < format.size() - 1 & amp; & amp;format.get(i).equals("x") & amp; & amp;(!format.get(i + 1) .equals("**")))||i == format.size()-1){<!-- -->
                biaoda.push("1");
                biaoda.push(format.get(i));
            }
            else if(format.get(i).equals("(")){<!-- -->
                int cout = 1;
                String bos = "";
                i + + ;
                while(cout > 0){<!-- -->
                    if(format.get(i).equals("("))cout + +;
                    if(format.get(i).equals(")"))cout--;
                    bos + = format. get(i);
                    i + + ;
                }
                i--;
                biaoda.push(complexQiu(bos.substring(0, bos.length()-1)));
                biaoda.push(bos.substring(0, bos.length()-1));

            }
            else if(format.get(i).equals("sin")||format.get(i).equals("cos")){<!-- -->
                String jidi = format. get(i);
                String cpsqiu = "";
                String cps = "";
                i + = 2;
                while(!format.get(i).equals(")")){<!-- -->
                   cps + = format. get(i);
                   i + + ;
                }
                if(!cps.equals("x")){<!-- -->
                    cpsqiu = complexQiu(cps);
                    // Derivation function original function
                    biaoda.push(chen(SanjQiu(jidi, cps), cpsqiu));
                    biaoda.push(jidi + "(" + cps + ")");
                }else{<!-- -->
                    biaoda.push(SanjQiu(jidi, cps));
                    biaoda.push(jidi + "(" + cps + ")");
                }
            }
            else if(format.get(i).equals("**")){<!-- -->
                String jidi = "";
                String zhi = "";
                String yuan = "";

                if(format.get(i-1).equals(")")){<!-- -->
                    jidi = biaoda. pop();
                    yuan = biaoda. pop();
                    biaoda.push(chen(miQiu(jidi,Integer.parseInt(zhi)), yuan));
                    biaoda.push(jidi + "**" + zhi);
                }
                else jidi = format. get(i - 1);
                zhi = format. get(i + 1);
                i + + ;
                // Derivation function + original function
                biaoda.push(miQiu(jidi, Integer.parseInt(zhi)));
                biaoda.push(jidi + "**" + zhi);
            }
            else if(format.get(i).equals("*")){<!-- -->
                operators. push(format. get(i));
            }
            else if(i<format.size()-1 & amp; & amp;(format.get(i).equals(" + ")||format.get(i).equals("-" ))){<!-- -->
                while(!operators.isEmpty() & amp; & amp; operators.peek().equals("*")){<!-- -->
                    operators. pop();
                    String op1 = biaoda. pop();
                    String Qop1 = biaoda. pop();
                    String op2 = biaoda. pop();
                    String Qop2 = biaoda. pop();
                    // derivative function
                    biaoda.push(chenQiu(op1, op2, Qop1, Qop2));
                    //Primitive
                    biaoda.push(chen(op2, op1));
                }
                if((format.get(i).equals("-") & amp; & amp;format.get(i + 1).equals(" + "))||(format.get(i ).equals(" + ") & amp; & amp; format.get(i + 1).equals("-"))) {<!-- -->
                    operators. push("-");
                    i + + ;
                    if(biaoda.isEmpty()){<!-- -->
                        String op = operators. pop();
                        if(op. equals("-")) format. set(i + 1, op + format. get(i + 1));
                    }
                }
                else if((format.get(i).equals("-") & amp; & amp;format.get(i + 1).equals("-"))||(format.get( i).equals(" + ") & amp; & amp;format.get(i + 1).equals(" + "))) {<!-- -->
                    operators. push(" + ");
                    i + + ;
                    if(biaoda.isEmpty()){<!-- -->
                        String op = operators. pop();
                        if(op. equals("-")) format. set(i + 1, op + format. get(i + 1));
                    }
                } else operators. push(format. get(i));


            }
        }

        while (!operators.isEmpty()) {<!-- -->
            String operator = operators. pop();
            if(operator.equals("*")){<!-- -->
                String op1 = biaoda. pop();
                String Qop1 = biaoda. pop();
                String op2 = biaoda. pop();
                String Qop2 = biaoda. pop();
                // derivative function
                biaoda.push(chenQiu(op1, op2, Qop1, Qop2));
                //Primitive
                biaoda.push(chen(op2, op1));
            }else{<!-- -->
                String yop1 = biaoda. pop();
                String op1 = biaoda. pop();
                String yop2 = biaoda. pop();
                String op2 = biaoda. pop();
                if(operator.equals(" + ")){<!-- -->
                    biaoda.push(complexPlus(op1,op2));
                    biaoda.push(complexPlus(yop1,yop2));
                }else{<!-- -->
                    biaoda.push(jian(op1,op2));
                    biaoda.push(jian(yop1,yop2));
                }

            }
        }
        biaoda. pop();
        return biaoda. pop();
    }

    public String Simplify(String s){<!-- -->
        String result = "";
        ArrayList<String> resdis = new ArrayList<>();
        ArrayList<String> plusdis = plusSplit(s);
        HashMap<String, String> alls = new HashMap<>();
        for(int i = 0; i<plusdis. size();i ++ ){<!-- -->
            ArrayList<String> multdis = MultiSplit(plusdis.get(i));
            HashMap<String, Integer> multSim = new HashMap<>();
            int xi = 1;

            if(multdis.get(0).charAt(0) == '-') {<!-- -->
                xi = -1;
                multdis.set(0, multdis.get(0).substring(1,multdis.get(0).length()));
            }
            for(int j = 0; j < multdis. size(); j ++ ){<!-- -->
                if(multdis.get(j).matches("\d + ")){<!-- -->
                    xi *= Integer. parseInt(multdis. get(j));
                }else if(multdis.get(j).matches("x")){<!-- -->
                    if(multSim.containsKey("x"))multSim.put("x", multSim.get("x") + 1);
                    else multSim. put("x", 1);
                }
                else if(multdis.get(j).matches("(.*)\*\*\d + ")){<!-- -->
                    String base = multdis.get(j).split("\*\*")[0];
                    int zhi = Integer.parseInt(multdis.get(j).split("\*\*")[1]);
                    if(multSim.containsKey(base))multSim.put(base, multSim.get(base) + zhi);
                    else multSim. put(base, zhi);
                }
                else if(multdis.get(j).matches("sin\(.*\)")||multdis.get(j).matches("cos\(. *\)")){<!-- -->
                    if(multSim.containsKey(multdis.get(j)))multSim.put(multdis.get(j), multSim.get(multdis.get(j)) + 1);
                    else multSim. put(multdis. get(j), 1);
                }
            }
            resdis.add(Integer.toString(xi));
            String index = "";
            String all = Integer. toString(xi);
            for(String key:multSim.keySet()){<!-- -->
                index = "";
                if(multSim.get(key) == 1)index += key;
                else index + =key + "**" + Integer.toString(multSim.get(key));
                resdis.add(index);
                if(alls. containsKey(index)) alls. put(index, complexPlus(alls. get(index), all));
                else alls. put(index, all);
                all = chen(all, index);
            }
            resdis.add(" + ");
        }
// System.out.println(alls);
        String index = "1";
        for(int i = 0; i<resdis. size();i ++ ){<!-- -->
// System.out.println(resdis.get(i));
            if(resdis.get(i).equals(" + ")){<!-- -->
                result = complexPlus(result, index);
                index = "1";
            }else{<!-- -->
                if(alls.containsKey(resdis.get(i)) & amp; & amp;!alls.get(resdis.get(i)).equals(index) & amp; & amp;!alls.get(resdis.get (i)).equals("no")){<!-- -->
                    index = "(" + alls.get(resdis.get(i)) + ")" + "*" + resdis.get(i);
                    alls. put(resdis. get(i), "no");
                }else if(alls.containsKey(resdis.get(i)) & amp; & amp;alls.get(resdis.get(i)).equals("no")){<!-- -->
                    index = "0";
                }else{<!-- -->
                    index = chen(index, resdis. get(i));
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {<!-- -->
        Qiudao q = new Qiudao();
        String yuan = q.complexQiu("5* x**4* sin(x)");
        System.out.println(yuan);
        String s = q.Simplify(yuan);
        System.out.println(s);
    }

}