通用 class 可以接受任何数字或任何其他可以添加的内容
Generic class that can take any numbers OR anything else that can be added
标题一定很混乱,让我解释一下:我正在写一个多项式,到目前为止它只适用于双系数。
我的想法是使这个 class 成为一个通用的,用户可以在其中指定系数的类型,例如 Polynomial<Double>
。现在系数不能是任何 class 的 objects,因为它们必须有加法、减法……方法。
为了解决这个问题,我制作了一个带有必要方法(加、减、乘、除)的算术接口,现在是 Polynomial<? extends Arithmetic>
。
但是由于Double没有实现这个接口,用户当然不能再使用Polynomial了。
我最后的问题是:如何使 Polynomial 通用化,使用户可以传递 java.lang.Number 的 subclass(或至少是 Double)或我的 Arithmetic 接口?如果做不到,我该怎么办?
一种方法是定义一个 Polynomial<T>
接口 ,它对 T
没有任何限制。
然后执行ArithmeticPolynomial implements Polynomial<Arithmetic>
。
然后你可以为 Number
类型做另一个实现,它只是重用 ArithmeticPolynomial
,像这样:NumberPolynomial<T extends Number> implements Polynomial<T>
。这将使用 wrapper/adapter class NumberArithmetic
。它将 Number
包装(适应)到 Arithmetic
.
如果我没理解错的话,就可以了。
我会使用递归数据结构来解决这个问题。
import java.util.ArrayList;
import java.util.List;
public class Polynomial {
private static class Term{
Object coefficient;
Object base;
Object power;
Term(Variable v){
this.coefficient = 1;
this.base = v;
this.power = 1;
}
Term(Number n){
this.coefficient = 1;
this.base = n;
this.power = 1;
}
public String toString(){
String tmp = "";
if(coefficient instanceof Number){
double c = ((Number) coefficient).doubleValue();
if(c != 1.0)
tmp += ((Number) coefficient).doubleValue();
}
if(coefficient instanceof Polynomial){ tmp += "(" + coefficient.toString() + ")";}
if(!tmp.isEmpty())
tmp += "•";
if(base instanceof Number){ tmp += ((Number) base).doubleValue(); }
if(base instanceof Variable){tmp += base.toString(); }
if(power instanceof Number){
double p = ((Number) power).doubleValue();
if(p != 1.0)
tmp += ((Number) power).doubleValue();
}
if(power instanceof Polynomial){tmp += base.toString(); }
// return
return tmp;
}
}
private List<Term> terms = new ArrayList<>();
public Polynomial add(Variable variable){
if(terms.isEmpty()){
terms.add(new Term(variable));
return this;
}
// search for same variable
for(Term t : terms){
if(t.base.equals(variable)){
addToCoefficient(t);
return this;
}
}
// similar term not found
terms.add(new Term(variable));
return this;
}
public Polynomial add(Number number){
if(terms.isEmpty()){
terms.add(new Term(number));
return this;
}
// search for any number
for(Term t : terms){
if(t.base instanceof Number){
t.base = ((Number) t.base).doubleValue() + number.doubleValue();
return this;
}
}
// default
return this;
}
private void addToCoefficient(Term t){
if(t.coefficient instanceof Number){ t.coefficient = ((Number) t.coefficient).doubleValue() + 1.0; }
if(t.coefficient instanceof Polynomial){ t.coefficient = ((Polynomial) t.coefficient).add(1); }
}
public String toString(){
String tmpA = "";
String tmpB = "";
for(Term t : terms) {
tmpA = t.toString();
tmpB += (tmpA.startsWith("+") || tmpB.startsWith("-")) ? tmpA : ("+" + tmpA);
}
return tmpB;
}
}
这个 class 本质上是将多项式存储为项列表。
每当需要操作(例如加法)时,多项式 class 决定:
- 我需要为此创建一个单独的术语吗
- 或者我是否需要将算术委托给现有术语
创建一个单独的术语是微不足道的事
委托给现有项通常意味着对该项的幂或系数进行某种操作。
这些要么是数字(在这种情况下很简单),要么是多项式,您只需递归到数据结构中即可。
我提供的代码可以这样调用:
public static void main(String[] args) {
Polynomial p = new Polynomial();
p.add(3)
.add(10)
.add(new Variable("a"))
.add(new Variable("a"));
System.out.println(p);
}
输出:
+13.0+2.0•a
标题一定很混乱,让我解释一下:我正在写一个多项式,到目前为止它只适用于双系数。
我的想法是使这个 class 成为一个通用的,用户可以在其中指定系数的类型,例如 Polynomial<Double>
。现在系数不能是任何 class 的 objects,因为它们必须有加法、减法……方法。
为了解决这个问题,我制作了一个带有必要方法(加、减、乘、除)的算术接口,现在是 Polynomial<? extends Arithmetic>
。
但是由于Double没有实现这个接口,用户当然不能再使用Polynomial了。
我最后的问题是:如何使 Polynomial 通用化,使用户可以传递 java.lang.Number 的 subclass(或至少是 Double)或我的 Arithmetic 接口?如果做不到,我该怎么办?
一种方法是定义一个 Polynomial<T>
接口 ,它对 T
没有任何限制。
然后执行ArithmeticPolynomial implements Polynomial<Arithmetic>
。
然后你可以为 Number
类型做另一个实现,它只是重用 ArithmeticPolynomial
,像这样:NumberPolynomial<T extends Number> implements Polynomial<T>
。这将使用 wrapper/adapter class NumberArithmetic
。它将 Number
包装(适应)到 Arithmetic
.
如果我没理解错的话,就可以了。
我会使用递归数据结构来解决这个问题。
import java.util.ArrayList;
import java.util.List;
public class Polynomial {
private static class Term{
Object coefficient;
Object base;
Object power;
Term(Variable v){
this.coefficient = 1;
this.base = v;
this.power = 1;
}
Term(Number n){
this.coefficient = 1;
this.base = n;
this.power = 1;
}
public String toString(){
String tmp = "";
if(coefficient instanceof Number){
double c = ((Number) coefficient).doubleValue();
if(c != 1.0)
tmp += ((Number) coefficient).doubleValue();
}
if(coefficient instanceof Polynomial){ tmp += "(" + coefficient.toString() + ")";}
if(!tmp.isEmpty())
tmp += "•";
if(base instanceof Number){ tmp += ((Number) base).doubleValue(); }
if(base instanceof Variable){tmp += base.toString(); }
if(power instanceof Number){
double p = ((Number) power).doubleValue();
if(p != 1.0)
tmp += ((Number) power).doubleValue();
}
if(power instanceof Polynomial){tmp += base.toString(); }
// return
return tmp;
}
}
private List<Term> terms = new ArrayList<>();
public Polynomial add(Variable variable){
if(terms.isEmpty()){
terms.add(new Term(variable));
return this;
}
// search for same variable
for(Term t : terms){
if(t.base.equals(variable)){
addToCoefficient(t);
return this;
}
}
// similar term not found
terms.add(new Term(variable));
return this;
}
public Polynomial add(Number number){
if(terms.isEmpty()){
terms.add(new Term(number));
return this;
}
// search for any number
for(Term t : terms){
if(t.base instanceof Number){
t.base = ((Number) t.base).doubleValue() + number.doubleValue();
return this;
}
}
// default
return this;
}
private void addToCoefficient(Term t){
if(t.coefficient instanceof Number){ t.coefficient = ((Number) t.coefficient).doubleValue() + 1.0; }
if(t.coefficient instanceof Polynomial){ t.coefficient = ((Polynomial) t.coefficient).add(1); }
}
public String toString(){
String tmpA = "";
String tmpB = "";
for(Term t : terms) {
tmpA = t.toString();
tmpB += (tmpA.startsWith("+") || tmpB.startsWith("-")) ? tmpA : ("+" + tmpA);
}
return tmpB;
}
}
这个 class 本质上是将多项式存储为项列表。
每当需要操作(例如加法)时,多项式 class 决定:
- 我需要为此创建一个单独的术语吗
- 或者我是否需要将算术委托给现有术语
创建一个单独的术语是微不足道的事
委托给现有项通常意味着对该项的幂或系数进行某种操作。
这些要么是数字(在这种情况下很简单),要么是多项式,您只需递归到数据结构中即可。
我提供的代码可以这样调用:
public static void main(String[] args) {
Polynomial p = new Polynomial();
p.add(3)
.add(10)
.add(new Variable("a"))
.add(new Variable("a"));
System.out.println(p);
}
输出:
+13.0+2.0•a