首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在数组中查找所有值最大的索引

在数组中查找所有值最大的索引
EN

Code Review用户
提问于 2013-12-12 06:58:41
回答 4查看 13.6K关注 0票数 8

下面的代码为我提供了数组最大值的索引:

代码语言:javascript
复制
public static void main(String[] args) {

    float[] elementList = new float[7];
    elementList[0] = 8F;
    elementList[1] = 5F;
    elementList[2] = 4F;
    elementList[3] = 3F;
    elementList[4] = 0F;
    elementList[5] = 8F;
    elementList[6] = 6F;
    // findLargestNumberLocations(elementList);
    largestNumbers(elementList);
}

private static void largestNumbers(float[] numbers) {

    float largeNumber = numbers[0];
    for (int i = 0; i < numbers.length; i++) {
        if (numbers[i] > largeNumber) {
            largeNumber = numbers[i];
        }
    }
    for (int j = 0; j < numbers.length; j++) {
        if(largeNumber == numbers[j]){
            System.out.println("largest number index "+j);
        }
    }
}

有什么优化的方法吗?

EN

回答 4

Code Review用户

回答已采纳

发布于 2013-12-12 15:57:49

在这种情况下,您的性能不会很糟糕,但是,对于非常大的数组,您可能会遇到问题。

还有,你的代码里有个bug .如果输入数组为空怎么办?然后,您将得到一个ArrayIndexOutOfBoundsException

代码语言:javascript
复制
float largeNumber = numbers[0];

做事情的方法总是不止一种,但是,我想在这里发布一个答案,因为一种可能的解决方案(根据数据大小可能比您的解决方案快,也可能不快)与最近发布的另一个CodeReview问题有着非常密切的关系。当我回答这个问题时,我只能想到一些人为的例子,说明什么时候使用前后增量是“正确的”。这是一个很好的例子.

见这里的答案:在for循环声明中增加多个变量是错误的做法吗?

因此,这里有一个很好的例子,说明了countindex在for循环中是如何和何时相关的,以及它们的增量方式。我在结尾有一些笔记:

代码语言:javascript
复制
private static int[] findLargeNumberIndices(float[] numbers) {

    // create an array of at least 8 members.
    // We may need to make this bigger during processing in case
    // there's more than 8 values with the same large value
    int[] indices = new int[Math.max(numbers.length / 16 , 8)];
    // how many large values do we have?
    int count = 0;
    // what is the largest value we have?
    float largeNumber = Float.NEGATIVE_INFINITY;
    for (int i = 0; i < numbers.length; i++) {
        if (numbers[i] > largeNumber) {
            // we have a new large number value... reset our history....
            largeNumber = numbers[i];
            // setting count to zero is enough to 'clear' our previous references.
            count = 0;
            // we know there's space for at least index 0. No need to check.
            // note how we post-increment - this is a 'pattern'.
            indices[count++] = i;
        } else if (numbers[i] == largeNumber) {
            // we have another large value.
            if (count == indices.length) {
                // need to make more space for indices... increase array by 25%
                // count >>> 2 is the same as count / 4 ....
                indices = Arrays.copyOf(indices, count + (count >>> 2));
            }
            // again, use the post-increment
            indices[count++] = i;
        }
    }
    // return the number of values that are valid only.
    return Arrays.copyOf(indices, count);
}

关于此代码的说明:

  1. 表示(System.out.println(...))现在在方法之外。
  2. 它分配一个“小”数组来存储索引。如果需要,这个数组将增长。
  3. 我为数组选择了“好的足够”的初始大小.但是一些数字的使用可能会提高性能。
  4. 没有真正的理由相信这段代码比这两个循环更快--创建数组可能比第二个循环更昂贵。
  5. 注意i索引是如何在for-循环中产生的,但是每次在数组中使用它时,count都是递增的。
票数 8
EN

Code Review用户

发布于 2013-12-12 07:08:04

您的代码不只是查找最大数字的索引。它找到最大的数字,然后再搜索与该值匹配的任何索引。

下面是一种使用较少搜索(伪代码)的方法:

代码语言:javascript
复制
largestValue = numbers[0];
vector largestIndices; // Will store all indices of largestValue as you search
largestIndices.add(0); // In case numbers[0] = the true largest value

for (i = 1; i < numbers.size(); i++) { // don't need to compare index 0
    if (numbers[i] > largestValue) {
        largestValue = numbers[i]; // Update largestValue
        largestIndices.clear();    // Get rid of indices of smaller values
        largestIndices.add(i);     // Add this index
    }
    else if (numbers[i] == largestValue) {
        largestIndices.add(i);     // Add this index
    }
}

for (j = 0; j < largestIndices.size(); j++) {
    // no searching necessary!
    print(largestIndices[j]);
}

这可能会使用更多的数据访问,但会节省搜索时间(对于大型数组来说很重要)。

票数 7
EN

Code Review用户

发布于 2013-12-12 08:41:12

函数启动后的新行是预期的吗?

代码语言:javascript
复制
private static void largestNumbers(float[] numbers) {

这个函数可以有一个更好的名称,函数应该有一个动词作为名称,而不是形容词。

代码语言:javascript
复制
private static void printLargestNumbersIndex(float[] numbers)

这是更详细的,但您立即知道该函数的作用。

代码语言:javascript
复制
float largeNumber = numbers[0];

很小,但我叫它largestNumber

代码语言:javascript
复制
for (int i = 0; i < numbers.length; i++) {
    if (numbers[i] > largeNumber) {
        largeNumber = numbers[i];
    }
}

foreach循环将更适合于这种用例。

代码语言:javascript
复制
for (float number : numbers) {
    if (number > largestNumber) {
        largestNumber = number;
    }
}

通常总是尝试使用foreach循环而不是for循环,除非您需要知道元素的索引(这在第二个循环中是这样的)。

代码语言:javascript
复制
for (int j = 0; j < numbers.length; j++) {

对我自己来说,我尽量避免一个字母的变量(只有坐标,x y z除外),这个观点肯定是有争议的和不标准的,但是我认为使用index作为变量会获得很大的可读性。

代码语言:javascript
复制
for (int index = 0; index < numbers.length; index++) {
代码语言:javascript
复制
if(largeNumber == numbers[j]){

请始终记住,将浮点数与==进行比较是有问题的。

代码语言:javascript
复制
System.out.println("largest number index "+j);

理想情况下,从代码结构和重用的角度来看,您的函数将返回包含所有已找到索引的int[]Collection<Integer>。这将使它很容易重用。

代码语言:javascript
复制
float[] elementList = new float[7];
elementList[0] = 8F;
elementList[1] = 5F;
elementList[2] = 4F;
elementList[3] = 3F;
elementList[4] = 0F;
elementList[5] = 8F;
elementList[6] = 6F;

可以使用值直接初始化数组。

代码语言:javascript
复制
float[] elementList = new float[] {8f, 5f, 4f, 3f, 0f, 8f, 6f};

而且,elementList并不是一个很好的名字。

票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/37201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档