4

arraylist をループして、3 つのインデックスごとに要素を徐々に削除しようとしています。配列リストの最後に到達したら、インデックスを最初にリセットしてから、配列リストを再度ループし、配列リストに要素が 1 つだけ残るまで、3 つのインデックスごとに要素を削除します。

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);

数時間実装しようとしましたが、まだ問題があります。arraylist の要素は次のようになります。

1, 2, 3, 4

1, 2, 4

1, 2

次に、3 番目の要素 (存在しなくなった) をチェックするときに、「範囲外のインデックス エラー」例外をスローします。最後の要素に到達したら、最初の要素にラップアラウンドし、配列を続行します。また、配列リストから要素を削除したら、最初からではなく、中断したところから開始したいと考えています。

4

7 に答える 7

3

船に乗り遅れただけかもしれませんが、これはあなたが求めていたものですか?

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);
                }
            }
        }
    }
}
于 2013-05-17T03:02:58.380 に答える
1

3 つおきの要素を一時リストに移動し、List#removeAll(Collection)各ループを終了するときに項目を削除するために使用できます...マスター リストが空になるまで...

于 2013-01-13T02:47:32.297 に答える
1

バックアップして、問題をアルゴリズム的に見てみましょう。

  • 最初の項目から数え始めます。
  • 次の項目に進み、カウントを増やします。次の項目がない場合は、最初に移動します。
  • カウントが「3」の場合、その項目を削除してカウントをリセットします。(またはモジュロ。)
  • リストに項目が 1 つ残っている場合は、停止します。

疑似コードを書きましょう:

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

このように見ると、これをすぐにコードに変換するのはかなり簡単です。

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
    }
  } 
}

つまり、何をしているのかを段階的に考え、それをゆっくりとコードに変換することが秘訣であることがわかります。最初の試みを修正することに追いついたのではないかと思います。コードを投げ出すことを恐れないでください。

于 2013-01-13T02:48:07.037 に答える
0

イテレータを使用してみることができます。遅いのであまり期待しないでください。

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 );
}
于 2013-01-13T09:48:01.073 に答える
0

int kのように、3 ずつインクリメントし続けるカウンターを使用できますk += 3。ただし、そのカウンターをインデックスとして使用して配列要素を追い出す前に、既に超えているかどうかを確認し、超えている場合は、カウンターからこの配列の長さを引きますk。またbreak、配列に要素が1つしか残っていないことがわかったら、ループから抜けてください。

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

sz - 1この例は、要素を削除する頻度、つまり回数をすぐに知っていることを示しています。

ちなみに、 にsz % 3は 0、1、2 の 3 つの結果しかありません。紙と 1 杯のコーヒーがあれば、ループをまったく実行せずに、それによってどの要素が生き残るかを調べることができます。

于 2013-01-13T02:35:11.567 に答える
0

remove を null に設定し、内側のループで null をスキップするだけです。

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++ と --i は醜く見えるかもしれませんが、うまく書き直せるかもしれません。)

于 2013-01-13T12:36:54.950 に答える