0

プログラミングクラスの追加単位の割り当てを行っています。OOP を実行しています。この例では、配列を取得して並べ替えます。すべてのソート コードは add メソッドに入ります。私はすでにいくつかのコードを持っていますが、それはある程度機能します。タイトルで述べたように、独自のコードを使用して独自のアルゴリズムを作成する必要があります。リスト内のすべての整数を最小から最大の順に並べ替えるにはどうすればよいですか? (整数は add メソッドで加算された値です。) インストラクターからの指示は次のとおりです。

• 新しい要素を配置する場所が見つかるまで、配列をたどっていきます。リストはすでにソートされているので、挿入する要素と少なくとも同じ大きさの要素が見つかるまで、要素を見続けることができます。

• 新しい要素の後に続くすべての要素、つまり停止した要素から最後までのすべての要素を下に移動します。これにより、新しい要素を配置できるスロットが作成されます。それらを移動する順序に注意してください。そうしないと、データが上書きされます。

これで、最初に停止した場所に新しい要素を挿入できます。これらすべてが add メソッドに入ります。

プログラムの 2 つのクラス:

   private int[] list;
   private int numElements = 0;



   //-------------------------------------------------------------
   // Constructor -- creates an integer list of a given size.
   //-------------------------------------------------------------
   public IntList(int size)
   {
      list = new int[size];
   }
   //------------------------------------------------------------
   // Adds an integer to the list. If the list is full,
   // prints a message and does nothing.
   //------------------------------------------------------------

   public void add(int value)
   {
      if (numElements == list.length){
      System.out.println("Can't add, list is full");
      }
      else
      { 
        list[numElements] = value;
        for(int i = 0; i < numElements; i++){
            //May be I should use a nested loop?
            //for(k = 0; k <)
             if(value < list[i]){
                 list[i+1]= list[i];
                 list[i]=value;
             }
       }
        numElements++;

            }


      }



   //-------------------------------------------------------------
   // Returns a string containing the elements of the list with their
   // indices.
   //-------------------------------------------------------------
   public String toString()
   {
      String returnString = "";
      for (int i=0; i<numElements; i++)
         returnString += i + ": " + list[i] + "\n";
      return returnString;
   }
}

他のクラス:

public class IntListThing {


public static void main(String[] args){

          IntList myList = new IntList(10);
          myList.add(84);
          myList.add(27);
          myList.add(250);
          myList.add(18);
          myList.add(94);
          myList.add(8);
          myList.add(87);
          System.out.println(myList);
       }
    }
4

5 に答える 5

4

適切な場所が見つかったら、ieif(value < list[i]){は true で、使用可能なすべての要素を右に移動します。を使用して 1 つだけ移動してlist[i+1]= list[i];います。

つまり、次のように小さなループを使用します。

  for(int j= numElements-1; j>=i; j--){
      list[j+1]= list[j];
  }
  list[i] = value;

注意:これがコンセプトです。指標と条件を調整してください。

編集:要素が挿入されたらすぐに中断する必要があることを言い忘れました。また、条件を修正しました。これが更新されたelseブロックコードです。

        list[numElements] = value;
        for(int i = 0; i < numElements; i++){
            //May be I should use a nested loop?
            //for(k = 0; k <)
             if(value < list[i]){
                 for(int j= numElements-1; j>=i; j--){
                      list[j+1]= list[j];
                  }
                  list[i] = value;
                  break;
            }
        }
        numElements++;
于 2012-11-09T20:46:27.097 に答える
2

教授に本当に影響を与えたい場合は、挿入スポットをバイナリ検索します。見つかったら、そのループを終了して別のループに入ります。ここでは、挿入スポットを超えてすべてを 1 か所右にコピーします。

編集

@Jan Dvorakが以下で鋭く指摘しているように、バイナリ検索でさえCPU時間とプログラミングの労力の無駄です:)

于 2012-11-09T20:56:05.457 に答える
1

これは宿題であるため、多くの人は直接コードを渡すことに消極的です。

ネストされたループを使用して、コメントで示唆したことが必要です。listこのループでの目標は、すべての要素を1 箇所ずつ「押し戻す」ことです。いくつかの考慮事項:

1) 配列の境界を必ず確認してください。配列が「いっぱい」の場合、制限を超えてプッシュすると、ArrayOutOfBoundsException.

2) ループを移動するときに、値を上書きしないように注意してください。後ろから始めて前に進むことをお勧めしますか?

于 2012-11-09T20:56:21.773 に答える
0

これを試して

class IntListThing  {
private int[] list;
private int numElements;

public IntListThing  ( int initial_capacity ) {
    list = new int[initial_capacity>0?initial_capacity:1];
    numElements = 0;
}

public void add(int value)  {
      if (numElements == list.length) list = Arrays.copyOf(list, list.length*2);
      int i = 0;
      for ( i = 0 ; i < numElements ; ++i ) 
          if ( value < list[i] ) break; 
      for ( int k = numElements ; k > i ; --k )
          list[k] = list[k-1];
      list[i] = value;
      ++numElements;
}

public String toString()  {
      String returnString = "";
      for (int i=0; i<numElements; i++)
         returnString += i + ": " + list[i] + "\n";
      return returnString;
   }


}

このようにして、配列がいっぱいになることを心配する必要もありません。必要に応じてサイズが変更されます。

Arrays クラスには、他にもあらゆる種類の便利なメソッドがあります。ぜひチェックしてみてください。誰かが使用を提案した binarySearch がありますが、この方法では配列をコピーするための線形の複雑さが既にあるため、ここでは非常に不適切です。対数時間で検索を行うポイントは何ですか。

私はあなたがその余分な信用を得ることを願っています.

さらに練習したい場合は、スペースを節約するために必要なときに配列のサイズを変更する remove メソッドを作成してみてください。これについて助けが必要な場合は、コメントでお知らせください。

于 2012-11-09T21:10:15.850 に答える
0

古典的な挿入ソートは、ソートされるまで要素を左にスワップし、次に次の要素に移動して、上書きされない場所に移動された要素のみを書き込むことによって機能します。

- input: array a
- for i from 1 to a.length-1: // the first element is already sorted!
  - temp = a[i];
  - j = i;
  - while (j>0 && a[j-1] < temp):
    - a[j] = a[j-1];
    - j = j-1;
  - endwhile
  - a[j] = temp;
- endfor
- output: a
于 2012-11-09T21:14:11.660 に答える