Java:将紧密数字与阈值匹配

时间:2017-05-14 05:07:11

标签: java arrays algorithm

假设您有 n 数组,每个数组中包含各种Integer个值。如何使用Java查找彼此之间 m 数字内的整数?

例如:

数组1:22, 23, 210, 221, 231, 236, 237, 251, 254, 278, 300, 316, 320

数组2:230

数组3:365, 366, 367, 373, 410, 413, 415, 417, 419

我希望有一个算法可以分析这些给定数组,其值为m=1并输出对231:Array1, 230:Array2。什么是最好的方法?

3 个答案:

答案 0 :(得分:2)

这是一种方法:

<强> 1。定义数组:

int [] arr1 = {22, 23, 210, 221, 231, 236, 237, 251, 254, 278, 300, 316, 320};
int [] arr2 = {230};
int [] arr3 = {365, 366, 367, 373, 410, 413, 415, 417, 419};

<强> 2。将所有数组放入集合:

List<Set<Integer>> sets = new ArrayList<>();
addSets(sets, arr1, arr2, arr3);

// Time: O(n * k) where n=number of arrays and k=size of largest array
private static void addSets(List<Set<Integer>> sets, int [] ... arrs)
{
    for (int [] arr : arrs)
    {
        Set<Integer> s = new HashSet<>();
        for (int i : arr)
        {
            s.add(i);
        }
        sets.add(s);
    }
}

第3。定义m

int m = 1;

<强> 4。查找群集:

List<String> pairs = findClusters(sets, m);

// Time: O(n^2 * k) where n=number of arrays and k=size of largest array
private static List<String> findClusters(List<Set<Integer>> sets, int m)
{
    // holds the pairs
    List<String> pairs = new ArrayList<>();

    for (int i = 0; i < sets.size() - 1; i++)
    {
        Set<Integer> primary = sets.get(i);

        for (int j = i + 1; j < sets.size(); j++)
        {
            Set<Integer> secondary = sets.get(j);

            for (int p : primary)
            {
                if (secondary.contains(p - m))
                {
                    pairs.add(p + ", " + (p-m));
                }
                if (secondary.contains(p + m))
                {
                    pairs.add(p + ", " + (p+m));
                }
            }
        }
    }
    return pairs;
}

<强> 5。打印对:

for (String pair : pairs)
    System.out.println(pair);

总运行时间

O((k * n) + (k * n^2))

答案 1 :(得分:1)

您可以使用java8流编写它:

public class Main{

    // This will give the stream of the data points from selected datasets
    public static Stream<List<Integer>> getPairs(List<Integer> a, List<Integer> b){
        return a.stream().flatMap(itemA -> b.stream().map(itemB -> Arrays.asList(itemA, itemB)));
    }

    // This will create the combination of datasets
    public static Stream<List<List<Integer>>> get(List<List<Integer>> dataSet) {
        return IntStream.range(0, dataSet.size()).boxed()
                .flatMap(i -> dataSet.subList(i+1, dataSet.size()).stream()
                        .map(secondry -> Arrays.asList(dataSet.get(i), secondry)));
    }

    public static void main (String[] args) {
        // data sets 
        List<Integer> list1 = Arrays.asList(22, 23, 210, 221, 231, 236, 237, 251, 254, 278, 300, 316, 320);
        List<Integer> list2 = Arrays.asList(230);
        List<Integer> list3 = Arrays.asList(365, 366, 367, 373, 410, 413, 415, 417, 419);

        // prepare dataset by adding any number of data cluster
        List<List<Integer>> dataset = Arrays.asList(list1, list2, list3);

        // create the required predicate and pass it to next statement
        Predicate<List<Integer>> predicate = points -> points.get(1) - points.get(0) == 1 || points.get(0) - points.get(1) == 1; 

        get(dataset).flatMap(datapair -> getPairs(datapair.get(0), datapair.get(1)))
                .filter(predicate).forEach(System.out::println);
  }
}

输出:

[231, 230]

您可以运行code here

答案 2 :(得分:0)

这是每对阵列的O(m + n)解决方案。它假定所有数组都已排序。

input x[m], y[n], threshold
i = 0;
j = 0;
while (i<m && j<n) {
    if ( abs(x[i]-y[j]) <= threshold) {
        return true;
    }
    if (x[i] <= y[j]) {
        i++;
    } else {
        j++;
    }
}

复杂性:O(n + m)

请注意,您可以将此转换为一个通过使用堆来考虑所有数组的循环,其复杂性将为O(n * log(k)),其中n是所有数组的总大小,k是数字阵列。