0

我有一个包含 50 个随机整数的数组列表。我要求用户删除一个号码,并且该号码的所有出现都从列表中删除。我这样做了

while (randInts.contains(removeInt) )
{
  if (randInts.get(i) == removeInt)                 
   randInts.remove(randInts.get(i));
   i++;             

 } 

 System.out.println("\n" + randInts.toString());
 System.out.println("\n" + randInts.size());`

问题的另一部分是提示用户输入另一个数字。每次出现第二个提示数字后,都会插入从上面删除的数字。当我不断收到 IndexOutOfBoundsException 时,我遇到了第二部分的问题。

4

8 回答 8

1

我看到了两个大问题:您没有限制i任何东西,并且您编写了一个 n^2 循环(您可以在线性时间内完成此操作)。

您正在缩小“列表”的大小......举个简单的例子:

假设您要删除所有实例5

给定一个看起来像的列表{1,2,3,5,5}

当 i = 3 时,您将删除前 5 个,使列表如下所示:{1,2,3,5}

然后您将尝试删除 i = 4 处的元素,但您要删除的元素现在实际上位于 i = 3,您将获得IndexOutOfBoundsException

您不想使用“包含”,因为这会将循环的最坏情况性能扩展到 n^2,这样会更快:

int size = randInts.size() - 1;
for (int i = size; i >= 0; i--){
   if (randInts.get(i).equals(removeInt))
       randInts.remove(i);
}
于 2013-09-16T20:47:52.547 回答
1

使用 aLinkedList代替;当您需要按顺序遍历而不是真正随机访问时,以及当您需要在列表中间插入和删除元素时,这是一个更好的选择。

您可以通过简单遍历列表的迭代器来完成您想要的(删除 的所有实例并在每个实例之后removeInt插入):removeIntinsertAfterInt

ListIterator<Integer> li = randInts.listIterator();
while(li.hasNext()) {
    int i = li.next();
    if(removeInt == i)     // assumes removeInt is an int; use equals() for Integer
        li.remove();
    if(insertAfterInt == i)
        li.add(removeInt);  // the iterator will skip this element, so it won't get removed
}
于 2013-09-17T21:42:22.477 回答
0

这是一种避免任何状态突变的方法(即randInts从不修改):

package so;

import java.util.ArrayList;

public class SO_18836900 {

  public static void main(String[] args) {

    // build a collection of random ints
    ArrayList<Integer> randInts = new ArrayList();
    for (int i = 0; i < 50; i ++) {
      randInts.add((int)(Math.random() * 5));
    }

    // create a collection with all 3s filtered out
    ArrayList<Integer> filtered = filterOut(randInts, 3);
    System.out.println(filtered);
    System.out.println(filtered.size());

    // create a collection with a 99 inserted after each 4
    ArrayList<Integer> insertedAfter = insertAfter(randInts, 4, 99);
    System.out.println(insertedAfter);
    System.out.println(insertedAfter.size());

  }

  static ArrayList<Integer> filterOut(Iterable<Integer> xs, int toRemove) {
    ArrayList<Integer> filteredInts = new ArrayList();
    for (int x : xs) {
      if (x != toRemove) filteredInts.add(x);
    }
    return filteredInts;
  }

  static ArrayList<Integer> insertAfter(Iterable<Integer> xs, int trigger, int toInsert) {
    ArrayList<Integer> insertedAfter = new ArrayList();
    for (int x : xs) {
      insertedAfter.add(x);
      if (x == trigger) insertedAfter.add(toInsert);
    }
    return insertedAfter;
  }

}
于 2013-09-16T21:34:03.610 回答
0
if (randInts.get(i) == removeInt)                 
randInts.remove(randInts.get(i));
i++;  

你永远不会检查停止条件。修复是:

while (randInts.contains(removeInt) )
{
    i=0;
   while(i<randInts.size()){

  if (randInts.get(i) == removeInt)                 
   randInts.remove(randInts.get(i));
   i++;             
}
 } 
于 2013-09-16T20:47:09.997 回答
0
while (randInts.contains(removeInt) )
{

   if(i<randInts.size());
    {
  if (randInts.get(i) == removeInt)                 
   randInts.remove(randInts.get(i));
     }//if
   i++;             

 }while
于 2013-09-16T20:48:37.333 回答
0

我猜您是从 50 个项目 ( randInts) 的集合开始并删除用户输入的项目 ( i)?

如果是这种情况,一旦您删除了一个项目,您的集合就只剩下 49 个索引并按索引get获取。尝试类似...

if (randInts.contains(i)){
     randInts.remove(randInts.indexOf(i));
}
于 2013-09-16T20:52:40.247 回答
0

这是 n^2,但它应该可以工作

int i = 0;

    while(i < loFnumbers.size()){
        if(loFnumbers.get(i) == removeInt){
            loFnumbers.remove(i);
            continue;
        }
        i++;

    }
于 2013-09-16T21:14:21.010 回答
-1

Dont use == on "Integers" you are comparing references.
Either unbox into int or use equals(

于 2013-09-16T20:45:17.107 回答