DulcetAirman

Merge Arrays

Feb 7th, 2022 (edited)
969
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.10 KB | None | 0 0
  1. package ch.claude_martin.utils;
  2.  
  3. import java.util.Arrays;
  4. import java.util.PrimitiveIterator.OfInt;
  5. import java.util.Spliterator;
  6. import java.util.Spliterators;
  7. import java.util.stream.IntStream;
  8. import java.util.stream.StreamSupport;
  9.  
  10. public class ArrayMerge {
  11.     public static void main(String[] args) {
  12.         mergeArrays(ints(-1, 0, 1, 2, 3), ints(4, 4, 5, 5), ints(5, 6, 7, 8), ints(-4, 8, 12)).forEach(i -> {
  13.             System.out.print(i);
  14.             System.out.print(',');
  15.         });
  16.         System.out.println();
  17.  
  18.     }
  19.  
  20.     static int[] ints(int... input) {
  21.         return input;
  22.     }
  23.  
  24.     /** Merges multiple sorted arrays of integers.
  25.      * The input is not altered by this method.  */
  26.     public static IntStream mergeArrays(int[]... input) {
  27.         final int k = input.length;
  28.         final long totalSize = Arrays.stream(input).mapToLong(a -> a.length).sum();
  29.         if (totalSize == 0)
  30.             return IntStream.empty();
  31.         // Array of the current indices of the next values to be returned:
  32.         final int[] indices = new int[k];
  33.         // Copy so that empty arrays can be replaced by null:
  34.         final int[][] copy = Arrays.copyOf(input, k);
  35.  
  36.         final OfInt ofInt = new OfInt() {
  37.             int nonNull = k;
  38.  
  39.             @Override
  40.             public boolean hasNext() {
  41.                 return this.nonNull > 0;
  42.             }
  43.  
  44.             @Override
  45.             public int nextInt() {
  46.                 int minValue = Integer.MAX_VALUE;
  47.                 int minIndex = -1;
  48.                 for (int j = 0; j < k; j++) {
  49.                     int[] array = copy[j];
  50.                     if (null == array)
  51.                         continue;
  52.                     final int value = array[indices[j]];
  53.                     if (value < minValue) {
  54.                         minValue = value;
  55.                         minIndex = j;
  56.                     }
  57.                 }
  58.  
  59.                 if (++indices[minIndex] == copy[minIndex].length) {
  60.                     copy[minIndex] = null;
  61.                     this.nonNull--;
  62.                 }
  63.                 return minValue;
  64.             }
  65.         };
  66.         var spliterator = Spliterators.spliterator(ofInt, totalSize,
  67.                 Spliterator.SIZED | Spliterator.ORDERED | Spliterator.SORTED | Spliterator.IMMUTABLE);
  68.  
  69.         return StreamSupport.intStream(spliterator, false);
  70.  
  71.     }
  72.  
  73.     /** Same method using ConcurrentSkipListMap, which is much faster. */
  74.     static IntStream parallelMergeArrays(int[]... input) {
  75.         var multiset = new ConcurrentSkipListMap<Integer, Integer>();
  76.         final long totalSize = Arrays.stream(input).mapToLong(a -> a.length).sum();
  77.         Arrays.stream(input).parallel().forEach(array -> {
  78.             for (var i : array)
  79.                 multiset.compute(i, (value, occurrences) -> null == occurrences ? 1 : occurrences + 1);
  80.         });
  81.  
  82.         final OfInt ofInt = new OfInt() {
  83.             int returned = 0;
  84.  
  85.             @Override
  86.             public boolean hasNext() {
  87.                 return this.returned < totalSize;
  88.             }
  89.  
  90.             @Override
  91.             public int nextInt() {
  92.                 final var first = multiset.firstEntry();
  93.                 final var key = first.getKey();
  94.                 final var occurrences = first.getValue();
  95.                 if (occurrences == 1) {
  96.                     multiset.remove(key);
  97.                 } else {
  98.                     //first.setValue(occurrences - 1);
  99.                     multiset.put(key, occurrences - 1);
  100.                 }
  101.                 this.returned++;
  102.                 return key;
  103.             }
  104.         };
  105.         var spliterator = Spliterators.spliterator(ofInt, totalSize,
  106.                 Spliterator.SIZED | Spliterator.ORDERED | Spliterator.SORTED | Spliterator.IMMUTABLE);
  107.  
  108.         return StreamSupport.intStream(spliterator, false);
  109.     }
  110.  
  111. }
Advertisement
Comments
  • User was banned
Add Comment
Please, Sign In to add comment