在ArrayList中查找最大的数

3
这是我在即将到来的考试前的练习,我正在尝试让用户输入一个数字。然后将数组array1中所有小于用户输入数字的元素放入新的ArrayList中。接着,我想要打印出该ArrayList中最大的数字。如果用户输入的数字比array1中的所有数字都小,则返回-1。 这是我的代码,但当我输入920时,它仍然返回-1,我认为在查找ArrayList中最大数字的代码中有问题。你们能告诉我错在哪里吗?
static Scanner sc = new Scanner(System.in);
static int[] array1 = {900, 885, 989, 1000, 1500, 1243, 999, 915};

public static int blabla(int[] a, int b) {

Integer d = -1;
ArrayList<Integer> al = new ArrayList<Integer>();

    for (int i = 0; i < array1.length; i++) { // this is to find all numbers in array1 that is below user's number, and add it to the ArrayList
        if (b > array1[i]) {
        al.add(array1[i]);
        } // if
    } // for

    outerloop: // and this function below is to find maximum number in ArrayList
    for (int g = (al.size()-1); g == 0; g--) {
                for (int j = 0; j <=(g-1); j++) {
                    if (al.get(j) > al.get(g)) {
                        break;
                    }
                    else if(j == (g-1)) {
                        if (al.get(g) > al.get(j)){
                            d = al.get(g);
                            break outerloop;
                        }
                    }
                } //for^2
    } // for
return d;
} // priceisright

在你的第一个循环中,你正在遍历新创建的 ArrayList 的元素,但是这个新创建的 ArrayList 是空的,所以这个循环甚至不会运行。你是不是想要遍历传递进来的 Array 的元素呢? - Kon
4
如果给变量和方法取一个有意义的名字,并将一些代码段委托给方法而不是放在一个大函数中,那么你将更容易理解自己的代码。同时,你也需要重新考虑你的算法,为什么需要两个嵌套循环来查找列表中的最大元素?实际上,只需要遍历每个元素并将其与当前最大值进行比较,如果更大,则更新当前最大值。此外,可以参考http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#max%28java.util.Collection%29。 - JB Nizet
1
你可以更高效地找到最大数(O(n^2)并不是很高效..)。为什么不一开始就排序呢? - TheLostMind
@TheLostMind 抱歉,你说的 (O(n^2) 是什么意思?我可以通过谷歌搜索了解如何排序,但我需要知道我的代码哪里出了问题 :/ - Rei
以下是我如何在一长队人中找到最高的人。如果队列为空,则没有最高的人。如果不是,则假设第一个人是最高的。然后我将其与第二个进行比较。如果第二个更高,他/她就成为了最高的人。然后我将第三个与当前最高的人进行比较,以此类推,直到队列末尾。对列表进行排序以查找最大值是一个坏主意。它修改了不需要修改的列表,并且它的时间复杂度是O(n*log(n)),而不是O(n)。 - JB Nizet
显示剩余4条评论
5个回答

4
static Scanner sc = new Scanner(System.in);
static int[] array1 = {900, 885, 989, 1000, 1500, 1243, 999, 915};

public static int blabla(int[] a, int b) {

Integer d = -1;
ArrayList<Integer> al = new ArrayList<Integer>();

此时,a1是一个空数组,因此a1.length = 0,这个循环不会被执行。

    for (int i = 0; i < a1.length; i++) { 
        // this is to find all numbers in array1 that is below user's number, 
        // and add it to the ArrayList
        if (b > a1[i]) {
            al.add(a1[i]);
        } // if
    } // for

a1仍然是空的,在第二个循环中也不会做任何事情。

    // and this function below is to find maximum number in ArrayList
    outerloop: 
    for (int g = (al.size()-1); g == 0; g--) {
                for (int j = 0; j <=(g-1); j++) {
                    if (al.get(j) > al.get(g)) {
                        break;
                    }
                    else if(j == (g-1)) {
                        if (al.get(g) > al.get(j)){
                            d = al.get(g);
                            break outerloop;
                        }
                    }
                } //for^2
    } // for
return d;
} // priceisright

这个怎么样?
    // Finds the greater value in values that is below maximum.
    // Returns -1 if none is found. 
    public static int blabla(int[] values, int maximum) {
      int best_value = -1;
      for (int value : values) {
        if (value < maximum && value > best_value) {
          best_value = value;
        }
      }

      return best_value;
    }

如果你的值保存在ArrayList中,你可以用List<Integer> values来代替int[] values


这样更好。不需要使用ArrayList,只需循环遍历数组,在用户输入下方找到最大值即可。 - francoisr
我认为他想将值存储在输入下面,如果不是这样,他为什么要那样做呢? - skoll
我估计(Rei请随时纠正我),中间的ArrayList只是一个临时存储,用于将操作分成两个简单的操作(提取有效值然后找到最大值),这是构建事物的好方法。在简单循环中同时执行两个操作在这种情况下是可能的,并且可以使算法更短更快,但并非总是如此,将复杂算法分解成小块通常是一个不错的方法。初始代码可能需要进行一些小修补,这就是为什么我指出了它存在的问题。 - Nicolas Defranoux
@NicolasDefranoux 实际上,'a1' 是数组1,我在粘贴时进行了编辑,以使其更易读,但我忘记编辑那个'a1',所以人们将其误认为是ArrayList 'al'。对此我感到抱歉 :/ - Rei

3

我猜他想要编写自己的max/sort函数,而不是使用库函数。 - TheMP
此函数实际上并不能帮助 OP 实现 - “将数组1中所有低于用户输入数字的元素放入新的 ArrayList 中”。 - TheLostMind
那很有效,谢谢 :D 自从第一个循环就把想要的数字放到新的ArrayList中。但我还想知道我的代码哪里有问题 :/ - Rei
这并没有真正回答问题:最初的代码有什么问题? - Nicolas Defranoux

1
如果你想使用 ArrayList,你可以通过线性时间检查最大值,如下所示:
public static Integer getMaximum(List<Integer> coll) {
  if (coll == null) {
    return null;
  }
  Integer i = coll.get(0);
  for (int t = 1; t < coll.size(); t++) {
    Integer v = coll.get(i);
    if (v != null && v > i) {
      i = v;
    }
  }
  return i;
}

或者,你可以将它改为SortedSet<Integer> set = new TreeSet<Integer>();,然后最大元素始终是set.last();

1

寻找数组或ArrayList(或任何集合)中的最大值的简单方法,而不使用内置方法,如.max

Int currentMax = 0

For (int i = 0; i < al.length; i++)
{
  If al[i] > currentMax
  {
    CurrentMax = al[i]
  }
}

我用手机回答这个问题,对于糟糕的缩进表示歉意,但你可以理解我的意思 :)


你必须希望列表中不仅包含负数。 - JB Nizet
我确实想过那个...但是可以将currentMax简单地设为你确定无法超越的一些负数...-999999999999应该可以(在有人评论之前也要更改为双精度)。 - Byron Coetsee
为什么不将currentMax设置为列表的第一个元素呢?这样总是正确的。而且相同的算法可以用于任何类型的列表,而不仅仅是数字列表。 - JB Nizet
是的,我想那也可以 - 不确定为什么我没有想到。哈哈。但概念是OP想要的 :) - Byron Coetsee

1

我会用一个更简单的循环来简化你的两个循环:

        for (int g = 0; g <=(al.size()-1); g++) { //for each value in your new array
            d = (al.get(g)>d)? al.get(g):d; //is current value higher than previous? if not keep old one
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接