<!--写在代码之前-->
相信这道题一定折磨不了前辈学长学姐,毕竟这道题对于刚入门学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+4