Here you can find the source of domainUnion(String[] a, String[] b)
Parameter | Description |
---|---|
a | a set of strings |
b | a set of strings |
public static String[] domainUnion(String[] a, String[] b)
//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; } }