通用 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