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.*;

public class Main {
    /** Clever union of String arrays.
     *// w  ww. j  av  a2s .  c  om
     * 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;
    }

    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 join(char sep, Object[] array) {
        return join(sep, Arrays.asList(array));
    }

    public static String join(char sep, Iterable it) {
        String s = "";
        for (Object o : it)
            s += (s.length() == 0 ? "" : sep) + o.toString();
        return s;
    }

    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 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 double[] join(double[] a, double[] b) {
        double[] 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)