[英]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;
如果只需要使用数组来解决这个任务,可能需要两遍来创建一个只包含有效索引的压缩数组:
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;
}
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.