我有下面的代码,除了在尝试从一个多项式中减去另一个多项式时的sub()函数之外,所有的代码似乎都工作得很好
p4 = p1.sub(p2);当我期望看到:x-2x^3+7x^5-2x^7-5x^8时,我看到了输出:x+3x^5-5x^8。我找不出我的代码出了什么问题,任何帮助都是非常感谢的。提前谢谢。
public class Polynomial {
public static final int MAX_NUMBER_OF_COEFFICIENTS = 30;
private int[] coefficients = new int[MAX_NUMBER_OF_COEFFICIENTS];
public Polynomial() {
}
public Polynomial(int coefficient, int exponent) {
coefficients[exponent] += coefficient;
}
public Polynomial(int[] newcoefficients) {
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
coefficients[i] += newcoefficients[i];
}
}
public void insert(int coefficient, int exponent) {
coefficients[exponent] += coefficient;
}
public Polynomial add(Polynomial otherPolynomial) {
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
if (otherPolynomial.coefficients[i] != 0)
this.coefficients[i] += otherPolynomial.coefficients[i];
}
return new Polynomial(this.coefficients);
}
public Polynomial sub(Polynomial otherPolynomial) {
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
if (otherPolynomial.coefficients[i] != 0)
this.coefficients[i] -= otherPolynomial.coefficients[i];
}
return new Polynomial(this.coefficients);
}
public void sub(int coefficient, int exponent) {
this.coefficients[exponent] -= coefficient;
}
public void remove(int exponent) {
coefficients[exponent] = 0;
}
public void printout() {
boolean firstPrint = false;
if (coefficients[0] != 0) {
System.out.print(coefficients[0]);
firstPrint = true;
}
for (int i = 1 ; i < MAX_NUMBER_OF_COEFFICIENTS; i ++) {
if (coefficients[i] != 0) {
if (firstPrint == false) {
System.out.print(coefficients[i] + "x^" + i);
firstPrint = true;
}
else {
System.out.print(" + " + coefficients[i] + "x^" + i);
}
}
}
System.out.println();
}
public static void main(String[] args) {
Polynomial p1 = new Polynomial(1,1);
Polynomial p2 = new Polynomial(2,3);
Polynomial p3 = new Polynomial();
Polynomial p4 = new Polynomial();
Polynomial p5 = new Polynomial(6,3);
try {
p1.insert(3,5);
p1.sub(5,8);
p1.printout();
p2.sub(4,5);
p2.add(new Polynomial(2,7));
p2.printout();
p3 = p1.add(p2);
p3.printout();
p4 = p1.sub(p2);
p4.printout();
p5.insert(2,5);
p5.remove(3);
p5.printout();
//p1.add(new Polynomial(2,-1));
}
catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Exponent cannot be negative. " + e);
}
}
}发布于 2017-02-13 19:31:20
函数的运行情况与预期一致。你不知道(也许你知道)的是,当你调用p3 = p1.add(p2);时,你会改变p1,然后返回一个带有p1系数的新多项式。因此,当你调用p4 = p1.sub(p2)时,你会得到与p3 = p1.add(p2)之前相同的p1。所以你得到的更多是这样的:
p3 = p1* = p1 + p2
p4 = p1** = p1* - p2
其中p1*是p1 + p2的结果。所以你现在拥有的是:
p4 = p1* - p2 = (p1 + p2) - p2 = p1
同样,如果你想返回新的多项式,不要改变现有的多项式。
同时更改函数add(Polynomial ..)和sub(Polynomial ..)
public Polynomial add(Polynomial otherPolynomial) {
int coeff[] = new int[MAX_NUMBER_OF_COEFFICIENTS];
System.arraycopy(this.coefficients, 0, coeff, 0, MAX_NUMBER_OF_COEFFICIENTS);
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
// why is this anyway?
//if (otherPolynomial.coefficients[i] != 0)
coeff[i] += otherPolynomial.coefficients[i];
}
return new Polynomial(coeff);
}
public Polynomial sub(Polynomial otherPolynomial) {
int coeff[] = new int[MAX_NUMBER_OF_COEFFICIENTS];
System.arraycopy(this.coefficients, 0, coeff, 0, MAX_NUMBER_OF_COEFFICIENTS);
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
// why is this anyway?
//if (otherPolynomial.coefficients[i] != 0)
coeff[i] -= otherPolynomial.coefficients[i];
}
return new Polynomial(coeff);
}这样,当你赋值(或调用拷贝构造函数) p3和p4时,你不会改变p1。
编辑:根据您的代码,不可能有一个函数,一旦添加到原始调用者,而一旦不改变它,这是您的程序想要的。当您调用p2.add(new Polynomial(2,7));时,您希望更改p2,同时又希望p1.add(p2)不更改p1,这在一个函数中是不可能实现的。
如果要使用问题中建议的输出,请更改
p2.add(new Polynomial(2,7));
至
p2 = p2.add(new Polynomial(2,7));
EDIT2:如果我想做这件事,我真的会用一种完全不同的方式。我将拥有所有返回类型为void的add/sub函数,以及两个返回新Polynomial和接受two Polynomials的静态add/sub函数。这些static方法不能在实例(如p1)上调用,但只能在类上调用。
因此,如果我在设计它,这将是我的代码:
public static Polynomial add(Polynomial p1, Polynomial p2){
Polynomial newPolynomial = new Polynomial();
for(int i=0;i< MAX_NUMBER_OF_COEFFICIENTS;i++)
newPolynomial.coefficients[i] = p1.coefficients[i]+p2.coefficients[i];
return newPolynomial;
}
public static Polynomial sub(Polynomial p1, Polynomial p2){
Polynomial newPolynomial = new Polynomial();
for(int i=0;i< MAX_NUMBER_OF_COEFFICIENTS;i++)
newPolynomial.coefficients[i] = p1.coefficients[i]-p2.coefficients[i];
return newPolynomial;
}
public void add(Polynomial otherPolynomial) {
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
coefficients[i] += otherPolynomial.coefficients[i];
}
}
public void sub(Polynomial otherPolynomial) {
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
coefficients[i] -= otherPolynomial.coefficients[i];
}
}当你以这种方式使用它时,你不能说p3.add(p1, p2)。这会将您的主代码更改为:
p1.insert(3,5);
p1.sub(5,8);
p1.printout();
p2.sub(4,5);
p2.add(new Polynomial(2,7));
p2.printout();
p3 = Polynomial.add(p1, p2);
p3.printout();
p4 = Polynomial.sub(p1, p2);
p4.printout();
p5.insert(2,5);
p5.remove(3);
p5.printout();如您所见,对于p3和p4,您将调用Polynomial.add和Polynomial.sub。您可以通过理解Math.*方法来更好地理解这一点。所有的Math库都是static,所以你不能创建它的实例,但是你可以说Math.abs...这里是相同的概念,您可以调用Polynomial.add,等等
发布于 2017-02-13 19:57:17
在您的代码中,您混合了两个概念。
1) (Immutable Ojects)您可以将多项式编码为不可变的,也就是说,add和sub不会改变成员字段,而是创建一个新的数组并返回一个新的对象-在这种情况下,必须编写
Polynomial p3 = p1.add(p2)而p1保持不变,-,或者
2) (可变对象)你应该把你的多项式编码成可变的,并且只返回这个(而不是创建一个返回新对象)--在这种情况下,你可以写
p1.add(p2)它类似于案例1中的p1 = p1.add(p2)。
在情况2)中,您可以执行以下操作
p1.add(p2).sub(p3)这类似于情况1中的p1 = p1.add(p2).sub(p3)。
由于您的操作是修改对象,因此您正在观察的内容称为副作用。避免副作用可能是编写使对象不可变的代码的主要动机之一。
试一试
public Polynomial add(Polynomial otherPolynomial) {
Polynomial result = new Polynomial();
for (int i = 0 ; i < MAX_NUMBER_OF_COEFFICIENTS; i++) {
if (otherPolynomial.coefficients[i] != 0)
result.coefficients[i] = this.coefficients[i] + otherPolynomial.coefficients[i];
}
return result;
}潜水艇也是如此。
搜索关键字不可变,可变和副作用,以了解更多详细信息。
发布于 2017-02-13 19:17:38
在我看来没问题,你先从行开始
Polynomial p1 = new Polynomial(1,1);它基本上是1*x,然后调用下面的代码行
p1.insert(3,5);它将数组的索引5设置为3,因此现在您有了1*x+3x^5,最后调用
p1.sub(5,8);它从数组的8索引中的值中减去5,因此现在您得到1x^1 + 3x^5 + -5x^8
https://stackoverflow.com/questions/42198612
复制相似问题