簡體   English   中英

Java:將緊密數字與閾值匹配

[英]Java: Matching close numbers with a threshold

假設你有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 什么是最好的方法?

這是一種方法:

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))

您可以使用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]

您可以在此處運行代碼

這是每對陣列的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是數組的數量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM