Java, Создание вектора объекта, который должен иметь n нулей в своем массиве после компиляции - PullRequest
0 голосов
/ 10 октября 2018

Это довольно сложно, но я постараюсь прояснить свой вопрос настолько, насколько это возможно.Поэтому я работаю над проектом, который занимается операциями с векторами.У меня есть разные классы для разных размеров: Vector3D, Vector5D и VectorND.Итак, у меня есть интерфейс и абстрактный класс, которые описывают такие методы, как Sum, Subtraction и т. Д. И для результата операции я создаю новый объект Vector, в который я помещаю координаты после sum / subtraction и т. Д. Так вот часть кода в качестве примера:

interface sample
{
    Vector Sum(Vector vec);
    Vector Subtraction(Vector vec);
    int Product(Vector vec);
    boolean Compare(Vector vec);
    String ToString();
}
abstract class Vector implements sample
{       
    int[] coordinates;  
     public Vector (int[] coordinates)
     {
         this.coordinates=coordinates;
     }
    protected abstract Vector resVec();     
    public Vector Sum(Vector vec)
    {   
        Vector result = resVec();
        if (this.coordinates.length == vec.coordinates.length)
        {
            for (int i = 0; i< vec.coordinates.length; i++)
            {
                result.coordinates[i] = this.coordinates[i] + vec.coordinates[i];
            }
        }
        else 
        {
            throw new ArithmeticException("Can't sum vectors of different length");
        }
        return result;

Вот защитник abstart Vector resVec ();- метод, который создает новый вектор с длиной, которая зависит от размерности векторов, с которыми мы работаем.Пример реализации для Vector3D:

class Vector3D extends Vector

{

public Vector3D(int n1,int n2,int n3) 
{
       super(new int[]{n1,n2,n3});
}

public Vector3D resVec()
{
    Vector3D resVec = new Vector3D(0,0,0);
    return resVec;
}

Итак, здесь я создаю новый вектор длиной 3 и заполняю его нулями.Мне нужно создать такой же вектор для VectorND.Примерно так:

    class VectorND extends Vector
{
    public VectorND(int...n) 
    {       
            super(n);
    }
    public VectorND resVec()
    {
        VectorND resVec = new VectorND();       
        return resVec;
    }

Есть идеи, как мне передать не объявленное количество нулей?Или, может быть, есть идея другой реализации?Спасибо!

Ответы [ 3 ]

0 голосов
/ 10 октября 2018

Прежде всего, вы можете использовать непатентованные значения, поскольку у вас возникнут проблемы, как только вам понадобится float или double для векторного типа.

public interface Vector<T extends Number>{

    T getX();

    void setX(T x);

    // [...]

    T length();

    T lengthSquared();
    // [...]

Чтобы решить эту проблему, добавьте вспомогательную переменную, котораясодержит размерность и затем обрабатывает математические операции как алгоритм / цикл.Таким образом, величина измерения больше не имеет значения, и вы также избегаете таких вопросов, как деление на ноль.

это пример для матрицы ... но подход такой же:

public final void multiply(float factor) {
    // in your case it would be getDimension() or something 
    for(int i = 0; i < getRows()*getColumns();++i){
        m[i]*=factor;
    }
}

О, и я знаю, что этот совет сложен для Java-разработчика, но не переусердствуйте с этим, иначе вы потеряете предварительную подготовку.

0 голосов
/ 10 октября 2018

Значения массивов автоматически устанавливаются по умолчанию.

int[] ints = new int[4];             // Filled with 0
double[] doubles = new double[5];    // Filled with 0.0
boolean[] booleans = new boolean[6]; // Filled with false
String[] strings = new String[7];    // Filled with null

Я не совсем уверен в ваших классах, но для многомерного матричного класса нужен только вариант one ,Значения могут быть сохранены в линеаризованном массиве с использованием вычисляемого индекса.

public class DoubleMatrix {
    final int[] sizes;
    final double[] values;

    public DoubleMatrix(int... sizes) {
        this.sizes = Arrays.copyOf(sizes, sizes.length); // Or sizes.clone()
        int valueCount = 1;
        for (int size : this.sizes) {
            assert size > 0 : "Every given size must be at least 1.";
            valueCount *= size;
        }
        values = new int[valueCount];
    }

    public int dimesion() {
        return sizes.length;
    }

    public double get(int... is) {
        int i = index(is);
        return values[i];
    }

    // new DoubleMatrix(2, 3, 4).set(3.14259, 0, 1, 2); // 24 values in 3D
    public void set(double x, int... is) {
        int i = index(is);
        values[i] = x;
    }

Сеттер немного нестандартен, сначала ставит значение из-за var-args is.Линеаризация от нескольких индексов к индексу в массиве values:

    private int index(int... is) {
        assert is.length == sizes.length: "Wrong number of indices.";
        int singleI = 0;
        for (int dim = 0; dim < sizes.length) {
            if (0 > is[dim] || is[dim] >= sizes[dim]) {
                throw new IndexOutOfBoundsException();
            }
            if (dim > 0) {
                singleI *= sizes[i - 1];
            }
            singleI += is[i];
        }
    }

(я не уверен, что вычисление индекса правильное.)

Вместоутверждает, что будет выбрасывать исключения времени выполнения (IllegalArgumentException).

Конечно, если бы get и set были protected, вы могли бы создать дочерний класс без var-args и иметь public get(int i, int j) дляDoubleMatrix2D.

0 голосов
/ 10 октября 2018

В методе resVec () вы можете заполнить массив нулями, а затем передать его своему суперструктору Vector.Так как ваш супер-конструктор принимает массив целых чисел, вы можете сделать что-то вроде этого:

public VectorND resVec(int n)
{
    int[] coordinates = new int[n];
    Arrays.fill(coordinates, 0);

    VectorND resVec = new VectorND(coordinates);       
    return resVec;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...