[英]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.