java 删除数组列表中的每个第三个元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14300094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 15:47:57  来源:igfitidea点击:

Remove every 3rd element in arraylist

javaarraysarraylist

提问by TeddyG

I am trying to loop through an arraylist and gradually remove an element every 3 indices. Once it gets to the end of the arraylist I want to reset the index back to the beginning, and then loop through the arraylist again, again removing an element every 3 indices until there is only one element left in the arraylist.

我正在尝试遍历一个数组列表,并每 3 个索引逐渐删除一个元素。一旦到达数组列表的末尾,我想将索引重置回开头,然后再次遍历数组列表,再次每 3 个索引删除一个元素,直到数组列表中只剩下一个元素。

The listOfWords is an array with a length of 3 that was previously filled.

listOfWords 是一个之前填充的长度为 3 的数组。

int listIndex = 0;

do
{           
    // just to display contents of arraylist    
    System.out.println(listOfPlayers);

    for(int wordIndex = 0; wordIndex < listOfWords.length; wordIndex++
    {
        System.out.print("Player");
        System.out.print(listOfPlayers.get(wordIndex));
        System.out.println("");
        listIndex = wordIndex;                                  
    }           

    listOfPlayers.remove(listOfPlayers.get(listIndex)); 
}
while(listOfPlayers.size() > 1);

I have tried to implement for several hours yet I am still having trouble. Here's what happens to the elements of the arraylist:

我已经尝试实施了几个小时,但仍然遇到问题。这是 arraylist 的元素发生的情况:

1, 2, 3, 4

1, 2, 4

1, 2

Then it throws an 'index out of bounds error' exception when it checks for the third element (which no longer exists). Once it reaches the last element I want it to wrap around to the first element and continue through the array. I also want it to start where it left off and not from the beginning once it removes an element from the arraylist.

然后它在检查第三个元素(不再存在)时抛出“索引越界错误”异常。一旦它到达最后一个元素,我希望它环绕到第一个元素并继续遍历数组。我还希望它从它停止的地方开始,而不是从数组列表中删除一个元素后从头开始。

回答by TeddyG

Maybe I have just missed the boat, but is this what you were after?

也许我刚刚错过了船,但这就是你所追求的吗?

import java.util.ArrayList;
import java.util.Random;

public class Test {

    public static void main(String[] args) {

        ArrayList<Integer> numbers = new ArrayList<Integer>();
        Random r = new Random();

        //Populate array with ten random elements
        for(int i = 0 ; i < 4; i++){
            numbers.add(r.nextInt());
        }

        while(numbers.size() > 1){
            for(int i = 0; i < numbers.size();i++){
                if(i%3 == 0){//Every 3rd element should be true
                    numbers.remove(i);
                }
            }
        }
    }
}

回答by MadProgrammer

You could move every third element to a temporary list then use List#removeAll(Collection)to remove the items when you finish each loop...until the master list was empty...

您可以将每三个元素移动到一个临时列表,然后List#removeAll(Collection)在完成每个循环时用于删除项目......直到主列表为空......

回答by Nathaniel Ford

Lets back up and look at the problem algorithmically.

让我们备份并从算法上看问题。

  • Start at the first item and start counting.
  • Go to the next item and increment your count. If there is no next item, go to the beginning.
  • If the count is '3', delete that item and reset count. (Or modulo.)
  • If there is one item left in the list, stop.
  • 从第一项开始并开始计数。
  • 转到下一个项目并增加您的计数。如果没有下一项,请转到开头。
  • 如果计数为“3”,则删除该项目并重置计数。(或取模。)
  • 如果列表中还剩下一项,请停止。

Lets write pseudocode:

让我们编写伪代码:

function (takes a list)
  remember what index in that list we're at
  remember whether this is the item we want to delete.

  loop until the list is size 1
    increment the item we're looking at.
    increment the delete count we're on

    should we delete?
      if so, delete!
      reset delete count

    are we at the end of the list?
      if so, reset our index

Looking at it this way, it's fairly easy to translate this immediately into code:

从这个角度来看,很容易将其立即转换为代码:

public void doIt(List<String> arrayList) {
  int index = 0;
  int count = 0;

  while(arrayList.size() != 1) {
    index = index + 1;
    count = count + 1; //increment count

    String word = arrayList.get(index);//get next item, and do stuff with it

    if (count == 3) {
      //note that the [Java API][1] allows you to remove by index
      arrayList.remove(index - 1);//otherwise you'll get an off-by-one error
      count = 0; //reset count
    }

    if (index = arrayList.size()) {
      index = 0; //reset index
    }
  } 
}

So, you can see the trick is to think step by step what you're doing, and then slowly translate that into code. I think you may have been caught up on fixing your initial attempt: never be afraid to throw code out.

所以,你可以看到诀窍是一步一步地思考你在做什么,然后慢慢地将它转化为代码。我认为您可能已经在修复您最初的尝试:永远不要害怕扔掉代码。

回答by Dan

You could try using an iterator. It's late irl so don't expect too much.

您可以尝试使用迭代器。现在已经晚了,所以不要期望太多。

public removeThirdIndex( listOfWords ) {
    Iterator iterator = listOfWords.iterator
    while( iterator.hasNext() ){
        iterator.next();
        iterator.next();
        iterator.next();
        iterator.remove();
    }
}


@Test
public void tester(){
    // JUnit test > main
    List listOfWords = ... // Add a collection data structure with "words"

    while( listOfWords.size() < 3 ) {
        removeThirdIndex( listOfWords ); // collections are mutable ;(
    }

    assertTrue( listOfWords.size() < 3 );
}

回答by Ondra ?i?ka

I would simply set the removed to null and then skip nulls in the inner loop.

我会简单地将删除的设置为空,然后在内循环中跳过空值。

boolean continue;
do {
   continue = false;
   for( int i = 2; i < list.length; i += 3 ){
      while( list.item(i++) == null &&  i < list.length );
      Sout("Player " + list.item(--i) );
      continue = true;
   }
} while (continue);

I'd choose this over unjustified shuffling of the array.

我会选择这个而不是不合理的阵列改组。

(The i++ and --i might seem ugly and may be rewritten nicely.)

( i++ 和 --i 可能看起来很丑,可以很好地重写。)

回答by Vadim Karavayev

Try the following code. It keeps on removing every nthelement in Listuntil one element is left.

试试下面的代码。它会不断删除所有nth元素,List直到剩下一个元素。

    List<Integer> array = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
    int nth = 3;
    int step = nth - 1;
    int benchmark = 0;

    while (array.size() > 1) {
        benchmark += step;
        benchmark = benchmark > array.size() - 1 ? benchmark % array.size() : benchmark;
        System.out.println(benchmark);
        array.remove(array.get(benchmark));
        System.out.println(array);
    }

回答by s.bandara

You could use a counter int kthat you keep incrementing by three, like k += 3. However, before you use that counter as an index to kick out any array element, check if you already went beyond and if so, subtract the length of this array from your counter k. Also make sure, to breakout of your loop once you find out the array has only one element left.

您可以使用一个int k不断递增 3的计数器,例如k += 3. 但是,在您使用该计数器作为索引来剔除任何数组元素之前,请检查您是否已经超出,如果已超出,请从您的 counter 中减去该数组的长度k。还要确保,break一旦发现数组只剩下一个元素就退出循环。

int k = -1;
int sz = list.length;
while (sz > 1)
{
    k += 3;
    if (k >= sz)
    {
        k -= sz;
    }
    list.remove(k);
    sz --;
}

This examples shows that you already know right away how often you will evict an element, i.e. sz - 1times.

这个例子表明你已经知道你驱逐一个元素的频率,即sz - 1次数。

By the way, sz % 3has only three possible results, 0, 1, 2. With a piece of paper and a cup of coffee you can find out what the surviving element will be depending on that, without running any loop at all!

顺便说一句,sz % 3只有三个可能的结果,0、1、2。用一张纸和一杯咖啡,你可以找出幸存的元素将取决于它,根本不需要运行任何循环!