7-3 一元多项式求导(类设计)

<!--写在代码之前-->

  相信这道题一定折磨不了前辈学长学姐,毕竟这道题对于刚入门学java的同学来说,确实有一定难度。之所以将这份代码写出来也是因为,在提交截至时,这份作业的通过率确实低的可怜。

  很多朋友也过来向我询问过思路,自己写的时候因为被最后一个天坑点卡了许久,所以也百度过,发现并没有有关这题的代码以及思路分享,所以才想着将这份代码分享出来,希望能帮到后面的学弟学妹们~

  详细思路在另外一篇PTA1-3作业总结里

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;
/*
 *       此类用于对多项式表达式求导
 *         by@徐良2021/03/23
 */
//Derivation 求导
public class Main  {
    
    public static void main(String[] args){
        Scanner in=new Scanner(System.in);
        String temp=in.nextLine();
        
        DvForString dv=new DvForString();
        dv.setPolynthic(temp);//预处理输入的字符串
        dv.print(); //根据合法性作出不同输出
//        System.out.println();
//        dv.printEveryElement();
    }
}
class DvForString{
    private static LinkedList<String> item;//存储各项,此题并不需要
    private static String sign,number,regex,regex1,regex2,regex3,concat,concatend,specialnum,end;//各项正则
//静态区,字符串
 static {
          //静态区只在类被加载时被执行一次
         item=new LinkedList<>();
         sign="(?:[+|-])";
         number="(?:([1-9](\\s*\\d*\\s*)*))";
         //全是常数项时的特判
         specialnum="((?:(\\s*([+|-]?[1-9]+\\s*\\d*)\\s*))*)";
         //带x项,允许系数中间内有空格
         //有不为0的系数和指数
         regex="(?:(([1-9](\\s*\\d*\\s*)*)\\s*\\*\\s*x\\s*\\^\\s*[+|-]?\\s*([1-9](\\s*\\d*\\s*)*)))";
         //x只有指数
         regex1="(?:(x\\s*\\^\\s*[+|-]?\\s*([1-9](\\s*\\d*\\s*)*)))";
         //x只有系数
         regex2="(?:(([1-9](\\s*\\d*\\s*)*)\\s*\\*\\s*x))";
         //x前面系数,指数都没有
         regex3="(?:x)";
         concat="("+regex+"|"+regex1+"|"+regex2+"|"+regex3+")";
         //数字和带x项或在一起构成多项式中的一项
         concatend="("+concat+"|"+number+")";
         //多项式表达式 ,首项可以无+,-,  后续项必须有
         end="(?:("+"\\s*"+sign+"?\\s*"+concatend+"(?:\\s*"+sign+"\\s*"+concatend+"\\s*)*"+"))";
    }
    //Polynthic 多项式
    private String Polynthic=null;
    
    public LinkedList<String> getItem() {
        return item;
    }
    //无参构造
    public DvForString(){}
    //有参构造,可以直接通过字符串数组名赋值另一个相同大小和类型的数组
    public DvForString(String polynthic) {
        this.Polynthic = polynthic;
    }
    //对私有变量获取和,赋值的方法
    public String getPolynthic() {
        return Polynthic;
    }
    public void setPolynthic(String polynthic) {
        this.Polynthic = polynthic;
    }
    //合法性检验
    private boolean isLegal() {
        boolean flag=true;
    
        String s=Polynthic;
        //全常数检验
        if(s.matches(specialnum)) 
            return true;
        //复杂多项式检验
        if(!s.matches(end)) flag=false;
        return flag;
    }
    //打印合法输入中每一项
    public  void printEveryElement() {
        System.out.println();
        if(isLegal()) { for(String e: item) System.out.println(e);}
        else System.out.println("Wrong Format");
    }
    //打印
    public void print() {
        if(isLegal()) printLegal();/合法结果打印
        else  printNotLegal();//不合法结果打印
    }
    //打印不合法输出
    private void printNotLegal() {
        System.out.println("Wrong Format");
    }
    //打印合法输出
    private  void printLegal() {
        //拷贝一份给字符串s
        String s=Polynthic;
        s=s.replace(" ","");

        char[] t=s.toCharArray();
        for(int i=0;i<s.length()-1;i++) 
            if(t[i]=='^'&&t[i+1]=='-') t[i+1]='#';
    
        //直接通过tostring转换字符数组会出错,所以一个个字符拼接
        String s1="";
        for(int i=0;i<t.length;i++) 
            s1=s1+t[i];
        //再来整体替换-
        s1=s1.replace("^+","^");
        s1=s1.replace("-","+-");
        
        //如果+出现在第一个位置会报异常,要用\\+
        String [] id=s1.split("\\+");
        
        //加号输出标记
        int flag=0;
        //无项时输出标记,标记若最终为0,最后输出0
        int lazy=0;
        //所有常数直接打印不需要特意放+,带x项,对于大于0项,前面有其他项要打印出来
    
        for(String e :id) {
            //切开后对每个元素进行分析处理,#要替换成-
            e=e.replace("#","-");
            if(e!=null) item.addLast(e);
            
            int start=e.indexOf("x");
            int mid=e.indexOf("*");
            int end=e.indexOf("^");
            //x,^都有
            if(start!=-1&&end!=-1) {
                //系数不为1,存在*
                if(mid!=-1) {
                    BigInteger pro=new BigInteger(e.substring(0,mid));
                    BigInteger pos=new BigInteger(e.substring(end+1,e.length()));
                    BigInteger xishu=pro.multiply(pos);//乘法
                    BigInteger zhishu=pos.subtract(new BigInteger(1+""));//减法
                    
                    if(zhishu.equals(new BigInteger(0+""))) System.out.print(xishu);
                    else {
                        if(xishu.equals(new BigInteger(1+""))) System.out.print("x^"+zhishu);
                        else if(xishu.equals(new BigInteger(-1+"")))System.out.print("-x^"+zhishu);
                        else {
                            if(    xishu.compareTo(new BigInteger(0+""))>0) 
                                if(flag==1) System.out.print("+");
                            System.out.print(xishu+"*x^"+zhishu);
                        }
                    }
                     lazy=1;
                     if(flag==0) flag=1;
                }
                //没有*,系数为负
                else {
                    if(e.charAt(0)=='-') {
                        BigInteger pos=new BigInteger(e.substring(end+1,e.length()));
                        BigInteger xishu=pos.multiply(new BigInteger(-1+""));//乘法
                        BigInteger zhishu=pos.subtract(new BigInteger(1+""));//减法
                        if(zhishu.equals(new BigInteger(0+""))) System.out.print(xishu);
                        else {
                            if(xishu.equals(new BigInteger(1+""))) System.out.print("x^"+zhishu);
                            else if(xishu.equals(new BigInteger(-1+"")))System.out.print("-x^"+zhishu);
                            else {
                                if(    xishu.compareTo(new BigInteger(0+""))>0) 
                                    if(flag==1) System.out.print("+");
                                System.out.print(xishu+"*x^"+zhishu);
                            }
                        }
                    }
                    //没*,系数不为负
                    else {
                        BigInteger pos=new BigInteger(e.substring(end+1,e.length()));
                        BigInteger xishu=pos.multiply(new BigInteger(1+""));//乘法
                        BigInteger zhishu=pos.subtract(new BigInteger(1+""));//减法
                        if(zhishu.equals(new BigInteger(0+""))) System.out.print(xishu);
                        else {
                            if(xishu.equals(new BigInteger(1+""))) System.out.print("x^"+zhishu);
                            else if(xishu.equals(new BigInteger(-1+"")))System.out.print("-x^"+zhishu);
                            else {
                                if(    xishu.compareTo(new BigInteger(0+""))>0) 
                                    if(flag==1) System.out.print("+");
                                System.out.print(xishu+"*x^"+zhishu);
                            }
                        }
                    }
                    lazy=1;
                    if(flag==0) flag=1;
                }
            }//^,x都存在的分界线
            //有x,没有指数
            else if(start!=-1) {
                //有*
                if(mid!=-1) { 
                    BigInteger num=new BigInteger(e.substring(0, mid));
//                    if(num.compareTo(new BigInteger(0+""))>0) if(flag==1) System.out.print("+");
                    System.out.print(num);                
                }
                //没有*
                else {
                    BigInteger num=null;
                    if(e.charAt(0)=='x') num=new BigInteger("1");
                    else if(e.charAt(0)=='-') num=new BigInteger("-1");
                    else 
                        num=new BigInteger(e.substring(0, start));
//                    if(num.compareTo(new BigInteger(0+""))>0) if(flag==1) System.out.print("+");
                    System.out.print(num);
                }
                lazy=1;
                if(flag==0) flag=1;
            }
            //常数
            else 
                System.out.print("");
        }//大for结尾
        if(lazy==0) System.out.println(0);
    }
}

 

  贴一张结果图,不同届的同学,测试点的提示可能不同~

  此题最大的天坑点,是求导得到的正数时不需要+的,如3*x+4*x  应该输出34而不是3+47-3 一元多项式求导(类设计)

 

上一篇:1011 A+B 和 C (15分)【java题解】【大整数】


下一篇:java中的进制转换与位运算