Java Unsigned Number Create unsignedIntersect2by2(final short[] set1, final int length1, final short[] set2, final int length2, final short[] buffer)

Here you can find the source of unsignedIntersect2by2(final short[] set1, final int length1, final short[] set2, final int length2, final short[] buffer)

Description

Intersect two sorted lists and write the result to the provided output array

License

Apache License

Parameter

Parameter Description
set1 first array
length1 length of first array
set2 second array
length2 length of second array
buffer output array

Return

cardinality of the intersection

Declaration

public static int unsignedIntersect2by2(final short[] set1, final int length1, final short[] set2,
        final int length2, final short[] buffer) 

Method Source Code

//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]&gt;= 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;

    }
}

Related

  1. unsignedInt(int value)
  2. unsignedInt2ByteLE(byte[] bytes, long value, int offset)
  3. unsignedInt2Long(int x)
  4. unsignedInt32ToBytes(long v)
  5. unsignedIntArray2signedIntArray(int[] myIntArray, int numberOfBytes)
  6. unsignedIntersects(short[] set1, int length1, short[] set2, int length2)
  7. unsignedIntToByteArray(long value)
  8. unsignedIntToHex(int i)
  9. unsignedIntToInt(byte[] b)