Общий класс, который может принимать любые числа ИЛИ все, что можно добавить - PullRequest
0 голосов
/ 11 апреля 2019

Название должно вводить в заблуждение, позвольте мне объяснить: я пишу полином, и пока он работает только с двойными коэффициентами.

Моя идея состоит в том, чтобы сделать этот класс общим, где пользователь может указать тип коэффициентов, например Polynomial<Double>. Теперь коэффициенты не могут быть объектами из любого класса, так как они должны иметь сложение, вычитание, ... методы.

Чтобы решить эту проблему, я сделал арифметический интерфейс с необходимыми методами (сложение, вычитание, умножение, деление) и теперь его Polynomial<? extends Arithmetic>.

Но так как Double не реализует этот интерфейс, конечно, пользователь больше не может использовать полином.

В заключение мой вопрос: как я могу сделать универсальный полином таким образом, чтобы пользователь мог передать подкласс java.lang.Number (или, по крайней мере, Double) ИЛИ мой арифметический интерфейс? Если это невозможно, что мне делать?

Ответы [ 2 ]

2 голосов
/ 11 апреля 2019

Один из способов - определить Polynomial<T> интерфейс , который не имеет ограничений на T.

Затем выполните реализацию ArithmeticPolynomial implements Polynomial<Arithmetic>.

* 1009.* Затем вы можете сделать другую реализацию для Number типов, которая просто повторно использует ArithmeticPolynomial, например: NumberPolynomial<T extends Number> implements Polynomial<T>.Это будет использовать класс оболочки / адаптера NumberArithmetic.Который оборачивает (адаптирует) Number к Arithmetic.

Если бы я вас правильно понял, это бы сделало.

1 голос
/ 11 апреля 2019

Я бы решил эту проблему с помощью рекурсивной структуры данных.

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;
}

}

Этот класс по существу хранит полином в виде списка терминов.

Всякий раз, когда операция являетсянеобходимо (например, дополнение) класс полинома решает:

  • нужно ли мне создать отдельный термин для этого
  • или мне нужно делегировать арифметику существующему термину

Создание отдельного термина является тривиальным случаем

Делегирование существующего термина обычно подразумевает какую-то операцию либо по мощности этого термина, либо по коэффициенту.

Либоэто числа (в этом случае easy peasy) или полиномы, и вы просто возвращаетесь в структуру данных.

Код, который я предоставил, можно назвать так:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...