【问题标题】:How to use findAny() to find a spesific value in a 2D Array如何使用 findAll() 在二维数组中查找特定值
【发布时间】:2021-08-22 20:24:26
【问题描述】:

我有一个二维数组如下

int[][] seatsPrices = {{10,10,10,10,10,10,10,10,10,10},
                        {10,10,10,10,10,10,10,10,10,10},
                        {10,10,10,10,10,10,10,10,10,10},
                        {10,10,20,20,20,20,20,20,10,10},
                        {10,10,20,20,20,20,20,20,10,10},
                        {10,10,20,20,20,20,20,20,10,10},
                        {20,20,30,30,40,40,30,30,20,20},
                        {20,30,30,40,50,50,40,30,30,20},
                        {30,40,50,50,50,50,50,50,40,30}};

我要求用户提供一个数字。假设他给了 20。所以,我想编写代码以迭代地将该值与 seatPrices 数组进行比较,并找到值是 20 的 seatPrices 数组的任何 i、j 索引,然后打印它。我可能应该使用 findAny() 但我不知道如何使用它。 注意:我只需要找到一个“20”并停止。因此,使用两个嵌套循环会给我带来一些问题。

【问题讨论】:

  • findAny 返回元素,而不是它的索引
  • @AlbertoSinigaglia 如果我能以某种方式找到与输入的任何匹配项,我可以设法返回它的索引,没问题。我无法找到匹配项
  • @ufukYavuz 为什么要进行额外的步骤?我认为没有任何标准的 java 函数可以通过二维数组,但是两个嵌套的 for 循环应该可以解决问题
  • 由于比较 int 值是显而易见的(使用==),我猜你在问如何Iterate through 2 dimensional array?迭代时只需比较特定位置的保持值。如果它拥有像 20 这样的搜索值,可以根据需要处理这些索引(将它们添加到某个列表中,打印它们等等)。
  • "一旦我找到与用户输入的匹配项,我需要退出循环。我找不到执行此操作的算法。它总是会产生一些问题 " 可能相关:How do I break out of nested loops in Java?

标签: java


【解决方案1】:

我不知道你为什么要使用 findAny(),只遍历数组并搜索 20 并在遇到一个时打印出 i,j 似乎要简单得多。

for (int i = 0; i < seatPrices.length; i++) {
    for (int j = 0; j < seatPrices[0].length; j++) {
        if (seatPrices[i][j] == 20) 
            System.out.println(i + " " + j);
    }
}

如果您对数组有所了解(比如它们已排序),您可以提出一种更快的算法来查找索引。

如果你只想找到一个:

boolean found = false;
for (int i = 0; i < seatPrices.length && !found; i++) {
    for (int j = 0; j < seatPrices[0].length && !found; j++) {
        if (seatPrices[i][j] == 20) {
            System.out.println(i + " " + j);
            found = true;
        }
    }
}

【讨论】:

  • 因此,您编写的代码将遍历数组的所有索引,其值为 20 并打印最少的“20”。我的意思是第 7 行第 9 列的“20”。但我需要让代码只找到第一个“20”并停止
  • 已编辑。搜索时间仍然是最坏的情况。
  • 他的数组似乎是有序的,他可以在那里进行二进制搜索而不是顺序搜索。这将减少到 log(n)。
  • @Alex 谢谢你最后的代码就是我要找的!
  • 另一种(在我看来,更好的)方法是将第一个循环命名为findLoop:,然后使用break findLoop;,而不是使用新变量found。跨度>
【解决方案2】:

.findAny().findFirst() 流方法并不适合您。它们都通过查找值而不是索引来工作。最好的方法是确实遍历您的数组,直到找到所需的值并在找到该值时停止迭代。你可以按照亚历克斯说的去做。

如果你知道你的数组是有序的(看起来是这样),你可以对它进行二进制搜索。 首先查看数组的中间,然后检查那里的值是否是你的值,或者它是否大于它,或者小于它。

  • 如果值(数组中间)是您的值 (20),则搜索 结束了。
  • 如果该值大于您的值,则该值(如果 present) 位于中间分割的左侧。
  • 如果 值小于你的值,那么你想要的值就在 你的分裂的右侧。

你只需要在你的值所在的数组一侧重复这个算法,直到你找到它。

示例一维算法:

int binarySearch(int arr[], int lIndex, int rIndex, int searchValue)
{
    if (rIndex >= lIndex) {
        int pivot = lIndex + (rIndex - lIndex) / 2;
        if (arr[pivot] == searchValue)
            return pivot;
        if (arr[pivot] > searchValue)
            return binarySearch(arr, lIndex, pivot - 1, searchValue);
        return binarySearch(arr, pivot + 1, rIndex, searchValue);
    }
    return -1;
}

您可以将二维数组展开为一维数组并获取索引,而不仅仅是将索引重新映射到二维索引:

x = index / size;
y = index % size;

【讨论】:

【解决方案3】:

如果您想为用户提供一个真正的任何值,我建议您获取所有适当的项目,然后再随机获取一个。 您可以收集所有与这样的单线匹配的项目:

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class SpecificValueIn2DArray {
    static int[][] seatsPrices = {{10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
    {10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
    {10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
    {10, 10, 20, 20, 20, 20, 20, 20, 10, 10},
    {10, 10, 20, 20, 20, 20, 20, 20, 10, 10},
    {10, 10, 20, 20, 20, 20, 20, 20, 10, 10},
    {20, 20, 30, 30, 40, 40, 30, 30, 20, 20},
    {20, 30, 30, 40, 50, 50, 40, 30, 30, 20},
    {30, 40, 50, 50, 50, 50, 50, 50, 40, 30}};

public List<int[]> getItemIndexCollection(int itemValue) {
    return IntStream.range(0, seatsPrices.length)
        .boxed()
        .flatMap(i ->
            IntStream.range(0, seatsPrices[i].length)
                .boxed()
                .map(j -> seatsPrices[i][j] == itemValue ? new int[]{i, j} : new int[]{-1, -1})
        )
        .filter(item -> item[0] != -1 && item[1] != -1)
        .collect(Collectors.toList());
}

}

并从结果列表中随机获取一个元素:

    final var actualResult = new SpecificValueIn2DArray().getItemIndexCollection(itemValue);
    final var random = new Random();
    final var pair = actualResult.get(random.nextInt(actualResult.size()));
    System.out.println(pair[0] + " " + pair[1]);
    System.out.println(SpecificValueIn2DArray.seatsPrices[pair[0]][pair[1]]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-27
    • 2023-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多