繁体   English   中英

如何从另一个数组返回具有某个 int 索引的数组

[英]How to return an array with the indexes of a certain int from another array

我是一名初学 Java 学生,我一直在尝试编写一种方法来列出数组中某个 int 的所有索引。 到目前为止,我所做的是将该 int 的值存储在另一个数组中的相应索引处,但我能做的最好的事情是将所有其他不等于原始 int 的索引的值设置为 -1。

我想我需要将值 i 存储在数组中并删除所有 -1,但我不知道该怎么做。 顺便说一下,这些值是 -1,因为我在这个程序中的所有数组都包含 0-100 之间的整数。 如果这个数组中可能的整数可以是任何数字,我会怎么做?

同样肯定有一种更简单或更有效的方法来做到这一点。

public static int[] maxValueIndex(int[] arr, int targetValue, int x) {
    
    int[] maxValue = new int[x];
    
    
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] == targetValue) {
            maxValue[i] = arr[i];
        } else {
            maxValue[i] = -1;
        }
        
    }       
    return maxValue;
    }

如果我正确理解了您的查询,那么您需要一个包含所有索引i的数组,使得arr[i]==targetValue 我们可以使用任何动态数据结构有效地实现这一点。 比如,使用一个ArrayList并继续一个一个地添加所有所需的索引,然后将 List 转换为一个数组并返回它。
像这样的东西:

List<Integer> index = new ArrayList<Integer>();
for (int i = 0; i < arr.length; i++)
{
    if (arr[i] == targetValue)
        index.add( i );
}
int[] maxValue = index.stream().mapToInt(Integer::intValue).toArray();
return maxValue;

如果只需要使用数组来解决这个任务,可能需要两遍来创建一个只包含有效索引的压缩数组:

  1. 找到匹配的数量,然后创建并填充一个紧凑数组
public static int[] getTargetIndexes(int targetValue, int ... arr) {
    int n = arr.length;
    int targetCount = 0;
    for (int i = 0; i < n; i++) {
        if (arr[i] == targetValue) {
            targetCount++;
        }
    } 
    
    int[] indexes = new int[targetCount];

    for (int i = 0, j = 0; j <targetCount && i < n; i++) {
        if (arr[i] == targetValue) {
            indexes[j++] = i;
        }
    }
    
    return indexes;
}
  1. 创建一个相同长度的数组,填充它,然后使用Arrays.copyOf
public static int[] getTargetIndexes(int targetValue, int ... arr) {
    int n = arr.length;
    int[] indexes = new int[n];

    int targetCount = 0;
    for (int i = 0; i < n; i++) {
        if (arr[i] == targetValue) {
            indexes[i] = i;
            targetCount++;
        } else {
            indexes[i] = -1;
        }
    }
    
    for (int i = 0, j = 0; j < targetCount && i < n; i++) {
        if (indexes[i] > -1) {
            indexes[j++] = i;
        }
    }
    
    return Arrays.copyOf(indexes, targetCount); // truncate bad indexes
}

此外,该方法的签名使用 vararg 将输入数组作为int序列传递—— vararg 参数int ... arr应该是最后一个。


如果可以使用Stream API,则可以方便地以声明方式解决任务:

public static int[] getTargetIndexes(int targetValue, int ... arr) {   
    return IntStream.range(0, arr.length) // get stream of indexes
            .filter(i -> arr[i] == targetValue) // keep only matching indexes
            .toArray(); // build output array
}

正如计算中经常遇到的情况一样,空间和时间之间存在权衡。

当然,问题是您不知道将有多少匹配项,您需要这样做来确定匹配索引数组的大小。

一种方法是创建一个足够大的数组以容纳最大匹配数,对匹配进行计数,然后返回正确大小的副本。 这可能会导致额外的空间:

static int[] targetIndex1(int[] arr, int target)
{
    int[] res = new int[arr.length];
    int m = 0;
    for(int i=0; i<arr.length; i++)
        if(arr[i] == target) res[m++] = i;
    
    return Arrays.copyOf(res, m);
}

另一种选择是遍历数组一次以计算匹配项,然后创建一个正确大小的数组 - 但现在您需要第二次通过数组来填充它。 这将需要额外的时间。

static int[] targetIndex2(int[] arr, int target)
{
    int m = 0;
    for(int i=0; i<arr.length; i++)
        if(arr[i] == target) m++;
    
    int[] res = new int[m];
    for(int i=0, j=0; j<m; i++)
        if(arr[i] == target) res[j++] = i;
    return res;
}

由于您是初学者,您可能应该使用这些方法之一。 然而,出于兴趣,还有另一个使用递归的选项,它似乎隐藏了额外的空间和额外的时间,当然这不是真的,因为您正在使用调用堆栈和方法调用会产生额外的成本。

static int[] targetIndex3(int[] arr, int target, int i, int m)
{
    if(i == arr.length)
    {
        return new int[m];
    }
    
    if(arr[i] == target)
    {
        int[] res = targetIndex3(arr, target, i+1, m+1);
        res[m] = i;
        return res;
    }
    else
    {
        return targetIndex3(arr, target, i+1, m);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM