Многомерный ArrayList -> Flatten -> Функция активации -> Deflat -> Многомерный ArrayList? - PullRequest
0 голосов
/ 23 мая 2018

В java, как я могу сгладить многомерный массив, передать его в функцию активации и наиболее эффективно извлечь исходную иерархию из массива ответов?

Например, блок необработанных данныхв формате

Структура входных данных:

[[.,.,.,.,.,],
[.,.,.],
[.,.,.,.,.,.,.,.,.],
[.,.,.,.,.,.,.,.]]

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

[.,.,.,.,.,.,. ... ]

Затем я хочу «дефлатировать» ответ, чтобы он отражал исходную иерархию.

Структура выходных данных:

[[.,.,.,.,.,],
[.,.,.],
[.,.,.,.,.,.,.,.,.],
[.,.,.,.,.,.,.,.]]

Предполагается, что функция активации обрабатывается последовательно, поэтому порядок не будет нарушен.Какой самый быстрый способ в Java, который я могу реализовать то же самое?Я не хочу поддерживать индексы для выравнивания и дефлаттинга, если я использую массивы.

1 Ответ

0 голосов
/ 23 мая 2018

Если вместо массива допустимо List, вы можете заключить массив в List.

. Это реализует List с get и set, а также реализует find, чтобы вы могли определить, где элемент с определенным индексом должен появляться в массиве.

static class Point {
    final int x, y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

static class Flattened<T> extends AbstractList<T> implements List<T> {
    private final T[][] subject;
    private final int flattenedLength;

    public Flattened(T[][] subject) {
        this.subject = subject;
        int flattenedLength = 0;
        for (T[] a : subject) {
            flattenedLength += a.length;
        }
        this.flattenedLength = flattenedLength;
    }

    @Override
    public T get(int index) {
        Point p = find(index);
        return subject[p.x][p.y];
    }

    @Override
    public T set(int index, T it) {
        Point p = find(index);
        T was = subject[p.x][p.y];
        subject[p.x][p.y] = it;
        return was;
    }

    public Point find(int index) {
        int pos = 0;
        // Walk the array to get the right row.
        for(int row = 0; row < subject.length; row++) {
            if(pos + subject[row].length <= index) {
                // Skip this row.
                pos += subject[row].length;
            } else {
                // Found it!!
                return new Point(row,index-pos);
            }
        }
        throw new IndexOutOfBoundsException("No item at position "+index);
    }

    @Override
    public int size() {
        return flattenedLength;
    }
}

public void test() {
    Integer[][] a = {
            {1},
            {2, 3, 4, 5},
            {6, 7, 8, 9, 10}
    };
    List<Integer> flat = new Flattened<>(a);
    System.out.println(flat);
}
...