Here you can find the source of unsignedIntersect2by2(final short[] set1, final int length1, final short[] set2, final int length2, final short[] buffer)
Parameter | Description |
---|---|
set1 | first array |
length1 | length of first array |
set2 | second array |
length2 | length of second array |
buffer | output array |
public static int unsignedIntersect2by2(final short[] set1, final int length1, final short[] set2, final int length2, final short[] buffer)
//package com.java2s; /*//w w w. j av a 2 s.c o m * (c) the authors Licensed under the Apache License, Version 2.0. */ public class Main { /** * Intersect two sorted lists and write the result to the provided output array * * @param set1 first array * @param length1 length of first array * @param set2 second array * @param length2 length of second array * @param buffer output array * @return cardinality of the intersection */ public static int unsignedIntersect2by2(final short[] set1, final int length1, final short[] set2, final int length2, final short[] buffer) { if (set1.length * 64 < set2.length) { return unsignedOneSidedGallopingIntersect2by2(set1, length1, set2, length2, buffer); } else if (set2.length * 64 < set1.length) { return unsignedOneSidedGallopingIntersect2by2(set2, length2, set1, length1, buffer); } else { return unsignedLocalIntersect2by2(set1, length1, set2, length2, buffer); } } protected static int unsignedOneSidedGallopingIntersect2by2(final short[] smallSet, final int smallLength, final short[] largeSet, final int largeLength, final short[] buffer) { if (0 == smallLength) { return 0; } int k1 = 0; int k2 = 0; int pos = 0; short s1 = largeSet[k1]; short s2 = smallSet[k2]; while (true) { if (toIntUnsigned(s1) < toIntUnsigned(s2)) { k1 = advanceUntil(largeSet, k1, largeLength, s2); if (k1 == largeLength) { break; } s1 = largeSet[k1]; } if (toIntUnsigned(s2) < toIntUnsigned(s1)) { ++k2; if (k2 == smallLength) { break; } s2 = smallSet[k2]; } else { // (set2[k2] == set1[k1]) buffer[pos++] = s2; ++k2; if (k2 == smallLength) { break; } s2 = smallSet[k2]; k1 = advanceUntil(largeSet, k1, largeLength, s2); if (k1 == largeLength) { break; } s1 = largeSet[k1]; } } return pos; } protected static int unsignedLocalIntersect2by2(final short[] set1, final int length1, final short[] set2, final int length2, final short[] buffer) { if ((0 == length1) || (0 == length2)) { return 0; } int k1 = 0; int k2 = 0; int pos = 0; short s1 = set1[k1]; short s2 = set2[k2]; mainwhile: while (true) { int v1 = toIntUnsigned(s1); int v2 = toIntUnsigned(s2); if (v2 < v1) { do { ++k2; if (k2 == length2) { break mainwhile; } s2 = set2[k2]; v2 = toIntUnsigned(s2); } while (v2 < v1); } if (v1 < v2) { do { ++k1; if (k1 == length1) { break mainwhile; } s1 = set1[k1]; v1 = toIntUnsigned(s1); } while (v1 < v2); } else { // (set2[k2] == set1[k1]) buffer[pos++] = s1; ++k1; if (k1 == length1) { break; } ++k2; if (k2 == length2) { break; } s1 = set1[k1]; s2 = set2[k2]; } } return pos; } protected static int toIntUnsigned(short x) { return x & 0xFFFF; } /** * Find the smallest integer larger than pos such that array[pos]>= min. If none can be found, * return length. Based on code by O. Kaser. * * @param array array to search within * @param pos starting position of the search * @param length length of the array to search * @param min minimum value * @return x greater than pos such that array[pos] is at least as large as min, pos is is equal to * length if it is not possible. */ public static int advanceUntil(short[] array, int pos, int length, short min) { int lower = pos + 1; // special handling for a possibly common sequential case if (lower >= length || toIntUnsigned(array[lower]) >= toIntUnsigned(min)) { return lower; } int spansize = 1; // could set larger // bootstrap an upper limit while (lower + spansize < length && toIntUnsigned(array[lower + spansize]) < toIntUnsigned(min)) { spansize *= 2; // hoping for compiler will reduce to } // shift int upper = (lower + spansize < length) ? lower + spansize : length - 1; // maybe we are lucky (could be common case when the seek ahead // expected // to be small and sequential will otherwise make us look bad) if (array[upper] == min) { return upper; } if (toIntUnsigned(array[upper]) < toIntUnsigned(min)) {// means // array // has no // item // >= min // pos = array.length; return length; } // we know that the next-smallest span was too small lower += (spansize / 2); // else begin binary search // invariant: array[lower]<min && array[upper]>min while (lower + 1 != upper) { int mid = (lower + upper) / 2; short arraymid = array[mid]; if (arraymid == min) { return mid; } else if (toIntUnsigned(arraymid) < toIntUnsigned(min)) { lower = mid; } else { upper = mid; } } return upper; } }