Java Array Union domainUnion(String[] a, String[] b)

Here you can find the source of domainUnion(String[] a, String[] b)

Description

Clever union of String arrays.

License

Apache License

Parameter

Parameter Description
a a set of strings
b a set of strings

Return

union of arrays

Declaration

public static String[] domainUnion(String[] a, String[] b) 

Method Source Code

//package com.java2s;
//License from project: Apache License 

import java.util.Arrays;
import java.util.Comparator;

public class Main {
    /** Clever union of String arrays.
     */*w w w .  j  a v a  2s.  c  o m*/
     * For union of numeric arrays (strings represent integers) it is expecting numeric ordering.
     * For pure string domains it is expecting lexicographical ordering.
     * For mixed domains it always expects lexicographical ordering since such a domain were produce
     * by a parser which sort string with Array.sort().
     *
     * PRECONDITION - string domain was sorted by Array.sort(String[]), integer domain by Array.sort(int[]) and switched to Strings !!!
     *
     * @param a a set of strings
     * @param b a set of strings
     * @return union of arrays
     */
    public static String[] domainUnion(String[] a, String[] b) {
        int cIinA = numInts(a);
        int cIinB = numInts(b);
        // Trivial case - all strings or ints, sorted
        if (cIinA == 0 && cIinB == 0 // only strings
                || cIinA == a.length && cIinB == b.length) // only integers
            return union(a, b, cIinA == 0);
        // Be little bit clever here: sort string representing numbers first and append
        // a,b were sorted by Array.sort() but can contain some numbers.
        // So sort numbers in numeric way, and then string in lexicographical order
        int[] ai = toInt(a, 0, cIinA);
        Arrays.sort(ai); // extract int part but sort it in numeric order
        int[] bi = toInt(b, 0, cIinB);
        Arrays.sort(bi);
        String[] ri = toString(union(ai, bi)); // integer part
        String[] si = union(a, b, cIinA, a.length - cIinA, cIinB, b.length
                - cIinB, true);
        return join(ri, si);
    }

    /** Returns number of strings which represents a number. */
    public static int numInts(String... a) {
        int cnt = 0;
        for (String s : a)
            if (isInt(s))
                cnt++;
        return cnt;
    }

    /** Union of given String arrays.
     *
     * The method expects ordering of domains in given order (lexicographical, numeric)
     *
     * @param a first array
     * @param b second array
     * @param lexo - true if domains are sorted in lexicographical order or false for numeric domains
     * @return union of values in given arrays.
     *
     * precondition lexo ? a,b are lexicographically sorted : a,b are sorted numerically
     * precondition a!=null && b!=null
     */
    public static String[] union(String[] a, String[] b, boolean lexo) {
        assert a != null && b != null : "Union expect non-null input!";
        return union(a, b, 0, a.length, 0, b.length, lexo);
    }

    public static String[] union(String[] a, String[] b, int aoff,
            int alen, int boff, int blen, boolean lexo) {
        assert a != null && b != null : "Union expect non-null input!";
        String[] r = new String[alen + blen];
        int ia = aoff, ib = boff, i = 0;
        while (ia < aoff + alen && ib < boff + blen) {
            int c = lexo ? a[ia].compareTo(b[ib]) : Integer.valueOf(a[ia])
                    .compareTo(Integer.valueOf(b[ib]));
            if (c < 0)
                r[i++] = a[ia++];
            else if (c == 0) {
                r[i++] = a[ia++];
                ib++;
            } else
                r[i++] = b[ib++];
        }
        if (ia < aoff + alen)
            while (ia < aoff + alen)
                r[i++] = a[ia++];
        if (ib < boff + blen)
            while (ib < boff + blen)
                r[i++] = b[ib++];
        return Arrays.copyOf(r, i);
    }

    /** Returns a union of given sorted arrays. */
    public static int[] union(int[] a, int[] b) {
        assert a != null && b != null : "Union expect non-null input!";
        int[] r = new int[a.length + b.length];
        int ia = 0, ib = 0, i = 0;
        while (ia < a.length && ib < b.length) {
            int c = a[ia] - b[ib];
            if (c < 0)
                r[i++] = a[ia++];
            else if (c == 0) {
                r[i++] = a[ia++];
                ib++;
            } else
                r[i++] = b[ib++];
        }
        if (ia < a.length)
            while (ia < a.length)
                r[i++] = a[ia++];
        if (ib < b.length)
            while (ib < b.length)
                r[i++] = b[ib++];
        return Arrays.copyOf(r, i);
    }

    public static int[] toInt(String[] a, int off, int len) {
        int[] res = new int[len];
        for (int i = 0; i < len; i++)
            res[i] = Integer.valueOf(a[off + i]);
        return res;
    }

    /**
     * Sort an integer array of indices based on values
     * Updates indices in place, keeps values the same
     * @param idxs indices
     * @param values values
     */
    public static void sort(final int[] idxs, final double[] values) {
        sort(idxs, values, 500);
    }

    public static void sort(final int[] idxs, final double[] values,
            int cutoff) {
        if (idxs.length < cutoff) {
            //hand-rolled insertion sort
            for (int i = 0; i < idxs.length; i++) {
                for (int j = i; j > 0
                        && values[idxs[j - 1]] > values[idxs[j]]; j--) {
                    int tmp = idxs[j];
                    idxs[j] = idxs[j - 1];
                    idxs[j - 1] = tmp;
                }
            }
        } else {
            Integer[] d = new Integer[idxs.length];
            for (int i = 0; i < idxs.length; ++i)
                d[i] = idxs[i];
            //      Arrays.parallelSort(d, new Comparator<Integer>() {
            Arrays.sort(d, new Comparator<Integer>() {
                @Override
                public int compare(Integer x, Integer y) {
                    return values[x] < values[y] ? -1
                            : (values[x] > values[y] ? 1 : 0);
                }
            });
            for (int i = 0; i < idxs.length; ++i)
                idxs[i] = d[i];
        }
    }

    public static String[] toString(long[] dom) {
        String[] result = new String[dom.length];
        for (int i = 0; i < dom.length; i++)
            result[i] = String.valueOf(dom[i]);
        return result;
    }

    public static String[] toString(int[] dom) {
        String[] result = new String[dom.length];
        for (int i = 0; i < dom.length; i++)
            result[i] = String.valueOf(dom[i]);
        return result;
    }

    public static String[] toString(Object[] ary) {
        String[] result = new String[ary.length];
        for (int i = 0; i < ary.length; i++) {
            Object o = ary[i];
            if (o != null && o.getClass().isArray()) {
                Class klazz = ary[i].getClass();
                result[i] = byte[].class.equals(klazz) ? Arrays
                        .toString((byte[]) o)
                        : short[].class.equals(klazz) ? Arrays
                                .toString((short[]) o)
                                : int[].class.equals(klazz) ? Arrays
                                        .toString((int[]) o)
                                        : long[].class.equals(klazz) ? Arrays
                                                .toString((long[]) o)
                                                : boolean[].class
                                                        .equals(klazz) ? Arrays
                                                        .toString((boolean[]) o)
                                                        : float[].class
                                                                .equals(klazz) ? Arrays
                                                                .toString((float[]) o)
                                                                : double[].class
                                                                        .equals(klazz) ? Arrays
                                                                        .toString((double[]) o)
                                                                        : Arrays.toString((Object[]) o);

            } else {
                result[i] = String.valueOf(o);
            }
        }
        return result;
    }

    public static long[] join(long[] a, long[] b) {
        long[] res = Arrays.copyOf(a, a.length + b.length);
        System.arraycopy(b, 0, res, a.length, b.length);
        return res;
    }

    public static float[] join(float[] a, float[] b) {
        float[] res = Arrays.copyOf(a, a.length + b.length);
        System.arraycopy(b, 0, res, a.length, b.length);
        return res;
    }

    public static <T> T[] join(T[] a, T[] b) {
        T[] res = Arrays.copyOf(a, a.length + b.length);
        System.arraycopy(b, 0, res, a.length, b.length);
        return res;
    }

    public static boolean isInt(String s) {
        int i = s.charAt(0) == '-' ? 1 : 0;
        for (; i < s.length(); i++)
            if (!Character.isDigit(s.charAt(i)))
                return false;
        return true;
    }
}

Related

  1. domainUnion(String[] a, String[] b)
  2. getUnionStr(String[] strAry, String unionChar, String appendChar)
  3. union(int[] a, int[] b)
  4. union(int[]... arrays)
  5. unionOfStringArrays(String x[], String y[])