Java, вложенный цикл, улучшить производительность - PullRequest
1 голос
/ 23 мая 2019

Мне нужно заполнить Список итераций (заданий) согласно рисунку.

Для выполнения задания, от hi до lo, разность генерирует операции факториального порядка n!.

Теперь я делю задачу как картинку.И очень важна оптимизация.

Например: (80-43) = 37 -> 37! set of complex operations with lists of polynomials and mathematical transformations.

enter image description here

int hi = 80;
int lo = 43;
int expanse = 12;
int overlap = 8;
int remmant = expanse - overlap;
int iterations = (int) Math.ceil((hi - lo - expanse) / (double) remmant) + 1;
List<List<Integer>> listFinishedTask = new ArrayList<>();
for (int i = 0; i < iterations; i++) {
  List<Integer> listIterations = new ArrayList<>();
  for (int j = (hi - i * (remmant)); j > Math.max(hi - i * (remmant) - expanse, lo - 1); j--) {
    listIterations.add(new Integer(j));
  }
  listFinishedTask.add(listIterations);
}

listFinishedTask.forEach(listIterations -> {
  System.out.println(Arrays.toString(listIterations.toArray()));
});

Вывод:

[80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69]
[76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65]
[72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61]
[68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57]
[64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53]
[60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49]
[56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45]
[52, 51, 50, 49, 48, 47, 46, 45, 44, 43]

Теперь, есть ли другой алгоритм для создания списка, похожего на картинку?

Ответы [ 2 ]

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

Как насчет использования List.subList?Это позволит избежать большого количества ненужного копирования:

// Create an ArrayList [80, 79, 78, ... , 44, 43]
List<Integer> list = new ArrayList<>();
for (int i = hi; i >= lo; i--) {
    list.add(i);
}

// Create an ArrayList of sublists
List<List<Integer>> subLists = new ArrayList<>();
for (int i = 0; i < list.size(); i += remmant) {
    subLists.add(list.subList(i, Math.min(list.size(), i + expanse)));
}

// Print each sublist
subLists.forEach(System.out::println);

Для expanse = 12 и overlap = 8 будет напечатано:

[80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69]
[76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65]
[72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61]
[68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57]
[64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53]
[60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49]
[56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45]
[52, 51, 50, 49, 48, 47, 46, 45, 44, 43]
[48, 47, 46, 45, 44, 43]
[44, 43]
0 голосов
/ 23 мая 2019

Просто сдвинь его!

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class SlidingTest {

    /* public static final class Sliding<T> extends AbstractList<List<T>> {

        private final List<T> list;
        private final int chunkSize;
        private final int overlap;

        public Sliding(List<T> list, int chunkSize, int overlap) {
            this.list = new ArrayList<>(list);
            this.chunkSize = chunkSize;
            this.overlap = overlap;
        }

        @Override
        public List<T> get(int index) {         
            int start = index * (chunkSize - overlap);
            int end = Math.min(start + chunkSize, list.size());

            if (start > end) {
                throw new IndexOutOfBoundsException("Index " + index + " is out of the list range <0," + (size() - 1) + ">");
            }

            return list.subList(start, end);
        }

        @Override
        public int size() {
            return (int) Math.ceil((double) (list.size() + chunkSize * (chunkSize - overlap)) / (double) chunkSize);
        }
    } */

    public static void main(String[] args) {
        try {
            int hi = 80;
            int lo = 43;
            int expanse = 12;
            int overlap = 8;
            int remmant = expanse - overlap;
            int iterations = (int) Math.ceil((hi - lo - expanse) / (double) remmant) + 1;
            /* List<Integer> numbers = IntStream.rangeClosed(lo, hi).boxed().map(j -> lo + (hi - j)).collect(Collectors.toList());
            Sliding<Integer> listFinishedTask = new Sliding<Integer>(numbers, expanse, overlap); */

            List<List<Integer>> listFinishedTask = IntStream.range(0, iterations).parallel().mapToObj(i -> {
                int start = Math.max(hi - i * (remmant) - expanse + 1, lo);
                int end = hi - i * (remmant);
                return IntStream.rangeClosed(start, end).boxed()
                    .map(j -> start + (end - j))
                    .collect(Collectors.toList());
            }).collect(Collectors.toList());

            listFinishedTask.forEach(System.out::println);  
        } catch(Exception ex) {
            ex.printStackTrace();
        }
    }

}
...