在 Java 8 中使用嵌套的 for 循环,找出给定的差异 [重复]

Posted

技术标签:

【中文标题】在 Java 8 中使用嵌套的 for 循环,找出给定的差异 [重复]【英文标题】:Using nested for loops in Java 8, to find out given difference [duplicate] 【发布时间】:2019-10-30 08:57:57 【问题描述】:

我在下面的代码中使用了嵌套的 for 循环,并且我有一些条件破坏了内部 for 循环,这提高了该代码的性能。

假设提供的列表已经排序。现在我想找到差值等于某个值的元素的数量,比如k

public static int getCount(List<Integer> list, int k) 
    int result = 0;
    for (int i = 0; i < list.size(); i++) 
        for (int j = i + 1; j < list.size(); j++) 
            if (list.get(j) - list.get(i) > k) 
                break;
            
            if (list.get(j) - list.get(i) == k) 
                result++;
            
        
    
    return result;

现在使用 Java 8 流的相同逻辑,这里跳过内循环我使用了 return 语句,但由于内循环没有被破坏,性能没有提高。

public static int getCount(List<Integer> list, int k) 
    int[] result =  0 ;
    IntStream.range(0, list.size()).forEach(i -> 
        IntStream.range(i + 1, list.size()).forEach(j -> 
            if (list.get(j) - list.get(i) >= k)
                return;
            if (list.get(j) - list.get(i) == k) 
                result[0]++;
            
        );
    );
    return result[0];

【问题讨论】:

@Alexei Kaigorodov,@Andy Turner,marked as duplicate 没有解释如何使用嵌套的 for 循环执行此操作。我的逻辑也是关于计算此类事件,链接没有解释。 副本清楚地表明,没有简单或惯用的方法可以突破 forEach 迭代。在 Java 9 中,您可以使用 takeWhile。但即使这样也是解决问题的低效方法:它仍然是二次的,而您可以线性地解决(但不能使用流)。 与您之前的问题一样,您担心的是提前终止循环的微小改进,而不是寻找具有较低渐近成本的方法。如果列表已排序,则可以使用二分查找代替内部循环。或者,您在一个循环中为元素 e 及其 e+k 位置在列表中维护两个索引。 @Holger, Or you maintain two indices into the list for an element e and its e+k position in a single loop. 你能解释一下这是什么意思吗?我知道e 是列表中的一个元素,所以看看e+k 是否也出现在列表中。像这样,我必须为每个元素重复。看来我的想法和你的观点不同。 index1 开头,e 的索引在0。查找index2e+k 的索引,例如通过Collections.binarySearch。现在进入循环:将index1 加一。由于列表已排序,新的e 大于旧的,因此e + k 的索引也必须大于旧的。提升index2 直到找到e+k 或达到大于e+k 的元素。重复直到index2 到达列表的末尾。然后,您无需再提出index1,因为相应的e+k 不会出现在列表中。所以你完成了。 k 越大,需要检查的元素就越少…… 【参考方案1】:

将您的内部IntStream.forEach() 替换为以下内容,看看它是否按预期工作:

IntStream.range(i + 1, list.size())
        .filter(j -> list.get(j) - list.get(i) == k)
        .forEach(j -> result[0]++);

【讨论】:

同样的问题,这里我们也没有打破内部循环,所以我遇到了性能问题。

以上是关于在 Java 8 中使用嵌套的 for 循环,找出给定的差异 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Java中跳出多重嵌套循环的方法

在java中,如何跳出当前的嵌套循环

java中for嵌套for循环的详细讲解?

如何在Java中嵌套for循环中使用字母增加值?

00015_循环嵌套

在JAVA中如何跳出当前的多重嵌套循环?