Java实现多项式求导(含简单幂函数和正余弦)
主要技术点:
①正则表达式匹配
②数学求导运算
③自定义排序
④大整数(BigInteger)运算
详细任务书
思路详解
拿到一个多项式字符串后,首先判断是否符合规范,不符合规范返回WRONG FORMAT!
,若符合规范,则拆分多项式,并去除多余空格和正负号后将其统一为标准多项式
a
x
b
(
s
i
n
x
)
c
(
c
o
s
x
)
d
ax^b(sinx)^c(cosx)^d
axb(sinx)c(cosx)d
保存四元组[a, b, c, d]
即可。
然后将标准多项式求导可得到三个多项式,
a
b
b
−
1
(
s
i
n
x
)
c
(
c
o
s
x
)
d
a
c
x
b
(
s
i
n
x
)
c
−
1
(
c
o
s
x
)
d
+
1
−
a
d
x
b
(
s
i
n
x
)
c
+
1
(
c
o
s
x
)
d
−
1
ab^{b-1}(sinx)^c(cosx)^d\\ acx^b(sinx)^{c-1}(cosx)^{d+1}\\ -adx^b(sinx)^{c+1}(cosx)^{d-1}
abb−1(sinx)c(cosx)dacxb(sinx)c−1(cosx)d+1−adxb(sinx)c+1(cosx)d−1
将得到的所有多项式按系数排序后合并,输出即可。
附源码
StrCut.java文件
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.math.BigInteger;
public class StrCut {
String polStr;
Vector polFull;
Vector ratFull;
BigInteger aX;
BigInteger xExp;
BigInteger sExp;
BigInteger cExp;
String part[] = new String[1000];
int len;
final String ADDORDE = "[-+]?";
// final String INTX = "[-+]?[0-9]+";
final String POLINT = "([0-9]*)?\\*?";
final String POLEXP = "(x(\\^[+-]?[0-9]+)?)?";
final String POLPART = ADDORDE + POLINT + POLEXP;
// final String EMPTY = "\\s*";
// final String POLFULL = "^("+ADDORDE + EMPTY + POLINT + EMPTY + POLEXP +
// ")+$";
final String POLPARTA = "[-+]?" + "([0-9]*)?\\s*\\*?\\s*" + "(x\\s*(\\^\\s*[+-]?[0-9]+)?)?";
final String POLPARTB = "([0-9]*)?\\s*\\*?\\s*" + "(x\\s*(\\^\\s*[+-]?[0-9]+)?)?";
final String OPER1 = "(\\+\\+)|(\\-\\-)";
final String OPER2 = "(\\+\\-)|(\\-\\+)";
final String SIN = "sin\\(x\\)(\\^[+-]?[0-9]+)?";
final String COS = "cos\\(x\\)(\\^[+-]?[0-9]+)?";
final String POL = "x(\\^[+-]?[0-9]+)?";
final String EXP = "[+-]?[0-9]+";
final String NUM = "[0-9]+";
// final String
final String TRIA = "((sin)|(cos))\\s*\\(x\\)(\\s*\\^\\s*[+-]?[0-9]+)?";
final String TRIB = "[+-]?((sin)|(cos))\\s*\\(x\\)(\\s*\\^\\s*[+-]?[0-9]+)?";
final String CONX = "x\\s*(\\^\\s*[+-]?[0-9]+)?";
final String CON = "[+-]?(" + TRIA + "|" + CONX + "|" + NUM + ")(\\*\\s*(" + TRIA + "|" + CONX + "|" + NUM + "))+";
final String ERRORA = "[0-9]+\\s+[0-9]+";
final String ERRORB = "([+-][+-]\\s*[+-]\\s+[0-9]+)" + "|" + "([+-]\\s*[+-]\\s*[+-]x)";
final String ERRORC = "[0-9]+[a-z]";
final String ERRORD = "[^xsincos\\(\\)\\d\\s\\^\\*+-]";
final String ERRORE = "(\\*\\s*[+-])|(\\^[+-]+\\s+[0-9]+)";
final String ERRORF = "(\\+oo)|([+-][+-][+-][+-]+)";
final String ERLEF1 = "[sincos\\(\\)]";
final String ERLEF2 = "\\s";
final String ERLEF = ERLEF1 + "|" + ERLEF2;
StrCut() {
}
StrCut(String str1) {
this.polStr = str1;
len = 0;
this.sExp = BigInteger.valueOf(0);
this.cExp = BigInteger.valueOf(0);
this.aX = BigInteger.valueOf(1);
this.xExp = BigInteger.valueOf(0);
this.polFull = new Vector();
this.ratFull = new Vector();
}
boolean check() {
boolean ynTrue = false;
String str = this.polStr;
boolean yn1 = false, yn2 = false;
if (str.equals("")) {
yn1 = true;
}
if (this.standard(str).equals("")) {
yn2 = true;
}
// -------------------------------------------------
String er[] = { ERRORA, ERRORB, ERRORC, ERRORD, ERRORE, ERRORF };
boolean yn[] = new boolean[er.length];
for (int i = 0; i < er.length; i++) {
yn[i] = false;
Pattern p = Pattern.compile(er[i]);
Matcher m = p.matcher(polStr);
yn[i] = m.find();
/*
* if(yn[i]) System.out.println("str---> "+m.group());
* System.out.println((i+1)+"->"+yn[i]);
*/
}
// -------------------------------------------------
str = str.replaceAll(CON, "");
str = str.replaceAll(TRIB, "");
str = this.standard(str);
// -------------------------------------------------
boolean yn3 = false;
Pattern p1 = Pattern.compile(ERLEF);
Matcher m1 = p1.matcher(str);
yn3 = m1.find();
// -------------------------------------------------
boolean qw = false;
for (int i = 0; i < yn.length; i++) {
if (yn[i]) {
qw = true;
}
}
if (!yn1 && !yn2 && !yn3 && !qw)
ynTrue = true;
return ynTrue;
}
String standard(String str) {
String be = new String();
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) != ' ' && str.charAt(i) != '\t')
be += str.charAt(i);
}
be = be.replaceAll(OPER1, "+");
be = be.replaceAll(OPER2, "-");
return be;
}
void strCut() {
// 1.CON 2.TRIB 3.POLPARTA
String aStr = this.standard(this.polStr);
// System.out.println("standard--> "+ aStr);
String patt[] = { CON, TRIB, POLPARTA };
for (int i = 0; i < patt.length; i++) {
Pattern p = Pattern.compile(patt[i]);
Matcher m = p.matcher(aStr);
while (m.find()) {
this.part[this.len] = m.group();
this.len++;
}
aStr = aStr.replaceAll(patt[i], "");
}
this.len--;
for (int i = 0; i < this.len; i++) {
// System.out.println(i+1+" ---> "+this.part[i]);
this.ratFull.add(this.union(this.part[i]));
// System.out.println(this.ratFull);
}
}
Vector union(String str) {
this.sExp = BigInteger.valueOf(0);
this.cExp = BigInteger.valueOf(0);
this.aX = BigInteger.valueOf(1);
this.xExp = BigInteger.valueOf(0);
Vector sec = new Vector();
BigInteger op = new BigInteger("1");
if (str.charAt(0) == '-')
op = new BigInteger("-1");
BigInteger b = new BigInteger("0");
// sin|cos^e x^e num
String mat[] = { SIN, COS, POL, EXP, NUM };
Pattern p1 = Pattern.compile(SIN);
Pattern p2 = Pattern.compile(COS);
Pattern p3 = Pattern.compile(POL);
Pattern p4 = Pattern.compile(EXP);
Pattern p5 = Pattern.compile(NUM);
// ---------------------------------------------------sin(x)^a
Matcher m1 = p1.matcher(str);
while (m1.find()) {
String sinStr = m1.group();
// System.out.println("=======> "+sinStr);
if (sinStr.length() == 6) {
b = new BigInteger("1");
} else {
Matcher e1 = p4.matcher(sinStr);
if (e1.find()) {
String s = e1.group();
b = new BigInteger(s);
}
}
this.sExp = this.sExp.add(b);
}
str = str.replaceAll(SIN, "");
// ----------------------------------------------------cos(x)^a
Matcher m2 = p2.matcher(str);
while (m2.find()) {
String cosStr = m2.group();
// System.out.println("=======> "+cosStr);
if (cosStr.length() == 6) {
b = new BigInteger("1");
} else {
Matcher e2 = p4.matcher(cosStr);
if (e2.find()) {
String s = e2.group();
b = new BigInteger(s);
}
}
this.cExp = this.cExp.add(b);
}
str = str.replaceAll(COS, "");
// ------------------------------------------------------x^a
Matcher m3 = p3.matcher(str);
while (m3.find()) {
String pStr = m3.group();
// System.out.println("=======> "+pStr);
if (pStr.length() == 1) {
b = new BigInteger("1");
} else {
Matcher e3 = p4.matcher(pStr);
if (e3.find()) {
String s = e3.group();
b = new BigInteger(s);
}
}
this.xExp = this.xExp.add(b);
}
str = str.replaceAll(POL, "");
// ---------------------------------------------------[0-9]
Matcher m4 = p5.matcher(str);
while (m4.find()) {
String nStr = m4.group();
// System.out.println("=======> "+nStr);
Matcher e4 = p4.matcher(nStr);
if (e4.find()) {
String s = e4.group();
b = new BigInteger(s);
this.aX = this.aX.multiply(b);
}
}
this.aX = this.aX.multiply(op);
sec.add(this.aX);
sec.add(this.xExp);
sec.add(this.sExp);
sec.add(this.cExp);
//System.out.println(sec);
return sec;
}
}
DerMerge.java文件
import java.util.Vector;
import java.math.BigInteger;
public class DerMerge {
Vector ratV;
Vector derV;
BigInteger nA, xE, sE, cE;
DerMerge() {
}
DerMerge(Vector st) {
ratV = st;
derV = new Vector();
this.nA = BigInteger.valueOf(1);
this.xE = BigInteger.valueOf(0);
this.sE = BigInteger.valueOf(0);
this.cE = BigInteger.valueOf(0);
}
void merge() {
Vector ve = new Vector();
ve.add(derV.elementAt(0));
for (int i = 1; i < derV.size(); i++) {
Vector at = (Vector) derV.elementAt(i);
int j = 0;
boolean as = false;
for (j = 0; j < ve.size(); j++) {
Vector temp = (Vector) ve.elementAt(j);
BigInteger t1 = new BigInteger(temp.elementAt(1).toString());
BigInteger t2 = new BigInteger(at.elementAt(1).toString());
int by = t1.compareTo(t2);
if (by == 1) {
ve.add(j, at);
as = true;
break;
}
if (by == 0) {
BigInteger s1 = new BigInteger(temp.elementAt(2).toString());
BigInteger s2 = new BigInteger(at.elementAt(2).toString());
BigInteger c1 = new BigInteger(temp.elementAt(3).toString());
BigInteger c2 = new BigInteger(at.elementAt(3).toString());
int sy = s1.compareTo(s2);
int cy = c1.compareTo(c2);
if (sy == 0 && cy == 0) {
BigInteger a1 = new BigInteger(temp.elementAt(0).toString());
BigInteger a2 = new BigInteger(at.elementAt(0).toString());
a1 = a1.add(a2);
BigInteger e1 = new BigInteger(temp.elementAt(1).toString());
if (a1.compareTo(new BigInteger("0")) == 0) {
ve.remove(j);
} else {
Vector a = new Vector();
a.add(a1);
a.add(e1);
a.add(s1);
a.add(c1);
ve.setElementAt(a, j);
}
as = true;
break;
}
}
}
if (!as) {
ve.add(at);
}
}
this.derV = ve;
/*
* System.out.println("after merge:"); for(int i=0;i<this.derV.size();i++) {
* System.out.println(derV.elementAt(i)); }
*/
}
void dervation() {
BigInteger a, b, c, d;
for (int i = 0; i < this.ratV.size(); i++) {
Vector temp = (Vector) this.ratV.elementAt(i);
this.nA = (BigInteger) temp.elementAt(0);
this.xE = (BigInteger) temp.elementAt(1);
this.sE = (BigInteger) temp.elementAt(2);
this.cE = (BigInteger) temp.elementAt(3);
// ----------------------------------1
Vector ve1 = new Vector();
a = this.nA.multiply(this.xE);
if (a.compareTo(new BigInteger("0")) != 0) {
b = this.xE.subtract(new BigInteger("1"));
c = this.sE;
d = this.cE;
ve1.add(a);
ve1.add(b);
ve1.add(c);
ve1.add(d);
this.derV.add(ve1);
}
// ----------------------------------2
Vector ve2 = new Vector();
a = this.nA.multiply(this.sE);
if (a.compareTo(new BigInteger("0")) != 0) {
b = this.xE;
c = this.sE.subtract(new BigInteger("1"));
d = this.cE.add(new BigInteger("1"));
ve2.add(a);
ve2.add(b);
ve2.add(c);
ve2.add(d);
this.derV.add(ve2);
}
// ----------------------------------3
Vector ve3 = new Vector();
a = this.nA.multiply(this.cE);
a = a.negate();
if (a.compareTo(new BigInteger("0")) != 0) {
b = this.xE;
c = this.sE.add(new BigInteger("1"));
d = this.cE.subtract(new BigInteger("1"));
ve3.add(a);
ve3.add(b);
ve3.add(c);
ve3.add(d);
this.derV.add(ve3);
}
}
// if derV is empty
if (this.derV.isEmpty()) {
Vector v = new Vector();
for (int i = 0; i <= 4; i++) {
v.add(BigInteger.valueOf(0));
}
this.derV.add(v);
}
/*
* System.out.println("after dervation:"); for(int i=0;i<this.derV.size();i++) {
* System.out.println(derV.elementAt(i)); }
*/
}
}
Output.java文件
import java.util.Vector;
import java.math.BigInteger;
public class Output {
Vector endPol;
String ans;
Output() {
};
Output(Vector pol) {
this.endPol = pol;
ans = "";
}
void putPol(BigInteger a, BigInteger exp) {
if (exp.compareTo(new BigInteger("0")) == 0) {
if (a.compareTo(new BigInteger("0")) == 1)
ans = ans + "+" + a.toString();
else
ans = ans + a.toString();
} else if (exp.compareTo(new BigInteger("1")) == 0) {
if (a.compareTo(new BigInteger("1")) == 0)
ans = ans + "+x";
else if (a.compareTo(new BigInteger("-1")) == 0)
ans = ans + "-x";
else if (a.compareTo(new BigInteger("0")) == 1)
ans = ans + "+" + a.toString() + "*x";
else
ans = ans + a.toString() + "*x";
} else {
if (a.compareTo(new BigInteger("1")) == 0)
ans = ans + "+x^" + exp.toString();
else if (a.compareTo(new BigInteger("-1")) == 0)
ans = ans + "-x^" + exp.toString();
else if (a.compareTo(new BigInteger("0")) == 1)
ans = ans + "+" + a.toString() + "*x^" + exp.toString();
else
ans = ans + a.toString() + "*x^" + exp.toString();
}
}
void putTri(BigInteger tre, String str) {
if (tre.compareTo(BigInteger.valueOf(0)) == 0) {
} else if (tre.compareTo(BigInteger.valueOf(1)) == 0) {
ans = ans + str;
} else {
ans = ans + str + "^" + tre.toString();
}
}
void putAll() {
if (this.endPol.size() == 0) {
System.out.println("0");
return;
}
for (int i = 0; i < this.endPol.size(); i++) {
Vector st = (Vector) this.endPol.elementAt(i);
BigInteger a = new BigInteger(st.elementAt(0).toString());
BigInteger exp = new BigInteger(st.elementAt(1).toString());
BigInteger sexp = new BigInteger(st.elementAt(2).toString());
BigInteger cexp = new BigInteger(st.elementAt(3).toString());
int yn1 = a.compareTo(BigInteger.valueOf(0));
int yn2 = exp.compareTo(BigInteger.valueOf(0));
int yn3 = sexp.compareTo(BigInteger.valueOf(0));
int yn4 = cexp.compareTo(BigInteger.valueOf(0));
this.ans = "";
this.putPol(a, exp);
if ((yn1 != 0 || yn2 != 0) && (yn3 != 0 || yn4 != 0))
ans = ans + "*";
this.putTri(sexp, "sin(x)");
if (yn3 != 0 && yn4 != 0)
ans = ans + "*";
this.putTri(cexp, "cos(x)");
ans = this.ans.replaceAll("\\+1\\*", "\\+");
ans = this.ans.replaceAll("\\-1\\*", "\\-");
System.out.print(this.ans);
}
System.out.println("");
}
}
Mian.java文件
import java.io.*;
import java.util.*;
import java.math.BigInteger;
public class Mian {
static String polStr;
Mian() {
this.polStr = "";
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine()) {
polStr = sc.nextLine();
StrCut sts = new StrCut(polStr);
boolean jk = sts.check();
if (jk) {
sts.strCut();
DerMerge dm = new DerMerge(sts.ratFull);
dm.dervation();
dm.merge();
Output op = new Output(dm.derV);
op.putAll();
} else {
System.out.println("WRONG FORMAT!");
}
}
}
}
测试及结果
上面最后一个测试用例应输出 WRONG FORMAT!(可在错误匹配中添加相应的错误格式)
这是大三的作业,还有部分测试用例未通过,部分bug未解决!可添加相应错误表达式检测,相比Vector使用ArrayList更为方便,还有好多需要优化的地方,大家酌情参考~