0

removeSomePoints という名前のメソッドを作成します。このメソッドはポイントの配列を取り、元の配列と同じポイントの新しい配列を返しますが、x 座標と y 座標の差が 20 未満のすべてのポイントを削除します。つまり、返される配列は、元の配列よりもサイズが小さい可能性があります。このメソッドは、元の配列をそのままにしておく必要があります。明確にするために: 次のポイントのいずれかが元の配列にあった場合、返される配列には含まれません。

100 90 (x と y の差は 10)

90 100 (x と y の差は 10)

3 22 (x と y の差は 19)

一方、返される配列には、次のポイントのいずれかが含まれます。

100 80 (x と y の差は 20)

80 100 (x と y の差は 20)

2 25 (x と y の差は 23)

私のコード:

   public static Point[] removeSomePoints(Point[] arr) 
   {

    int count = 0;      
    for (int i = 0; i < arr.length; i++) {
         if (Math.abs(arr[i].getX() - arr[i].getY()) > 19) {
            count++;
          }
         }

        Point[] finalArr = new Point[count];

        for (int i = 0; i < finalArr.length; i++) {
          if (Math.abs(arr[i].getX() - arr[i].getY()) > 19) {
               finalArr[i] = arr[i];
          }

     }

       return finalArr;
    }

何が問題なのか理解できないようです。配列を返していますが、何も変更しません。

4

4 に答える 4

1

N長さの入力配列で、一致するアイテムの数 (たとえば、 ) を決定するため、プログラムは現在機能していませんMNが 未満であることが保証されている場合、 (長さの) 入力配列のサブセットを反復処理し、そのサブセット内の一致を出力配列にコピーしてMいることに注意してください。これは単に正しくありません。N

これは学習プロジェクトだと思います。このレッスンの重要なポイントは、コードに適したデータ構造を選択することです。配列は、固定サイズのセットを扱う場合には優れていますが、可変サイズのセットにはあまり適していません。可変データの場合、リストは間違いなく最適な方法です。

それでは、いくつかの擬似コードを見てみましょう。

public static Point[] removeSomePoints(Point[] arr) {
    // If 'arr' is null, return null
    // If 'arr' is empty, return empty

    // Initialize a variable list structure, of at least arr.length in size
    // For each element in arr
    //     if element matches condition, add to variable list
    // End for
    // 
    // Convert variable list into array and return
}

一言で言えば、それがあなたのアルゴリズムです。それを実際のコードに変換します。

public static Point[] removeSomePoints(Point[] arr) {
    if(arr == null) return null;
    if(arr.length == 0) return new Point[0];

    List<Point> outputList = new ArrayList<Point>(arr.length);
    for(Point p : arr) {
        if (Math.abs(p.getX() - p.getY()) > 19) outputList.add(p);
    }

    return outputList.toArray(new Point[outputList.size());
 }

ListArrayListのドキュメントを参照して、それらがどのように機能するかをよりよく理解することを忘れないでください。

于 2013-01-18T22:28:34.017 に答える
0

他の人が述べたように、問題は 2 番目のループの論理的な欠陥によるものです。返される配列ではなく、元の配列を反復処理する必要があります。

ArrayListとを活かす答えresizeArrayはどちらも良い。@Perception の回答では中間データ構造として使用され、 @ ArrayListDreadPirateShawn の回答でArrayは中間データ構造として使用されます。最終的に、両方とも返される結果配列にサイズ変更されます。中間データ構造へのランダム アクセスは必要ないため、LinkedList代わりに使用することをお勧めします。リンクされたリストを使用すると、サイズを変更する必要がないため、時間とスペースを節約できる可能性があります。

public static Point[] removeSomePoints(Point[] arr) {
    if(arr == null) return null;
    if(arr.length == 0) return new Point[0];

    List<Point> outputList = new LinkedList<Point>();
    for(Point p : arr) {
        if (Math.abs(p.getX() - p.getY()) > 19) outputList.add(p);
    }

    return outputList.toArray(new Point[outputList.size()]);
}
于 2013-01-18T23:43:34.460 に答える
0

ロジックの主な欠陥は、生の配列で短い配列インデックスが使用されていることです。

これは、配列 [[90,100],[75,100],[85,100],[80,100]] が最初に 2 つの有効なエントリをカウントし、サイズ 2 の新しい配列を作成し、次に raw 配列から最初の 2 つのエントリをコピーして作成することを意味します。目的の [[75,100],[80,100]] ではなく [[90,100],[75,100]]。

1 つの方法として、「resizeArray()」関数を追加し (例: http://www.source-code.biz/snippets/java/3.htm )、最初のループ中に別のインデックス (たとえば、"count") は、新しい配列に追加するときにのみインクリメントされます。その後、新しい配列のサイズをターゲット サイズに縮小します。

そのようです:

public static Point[] removeSomePoints(Point[] arr)
{
    int count = 0;

    Point[] finalArr = new Point[arr.length];

    for (int i = 0; i < arr.length; i++)
    {
        if (Math.abs(arr[i].getX() - arr[i].getY()) > 19)
        {
            finalArr[count] = arr[i];
            count++;
        }
    }

    return (Point[])resizeArray(finalArr, count);
}
于 2013-01-18T21:51:41.997 に答える
0

2 番目のループは次のようになります。

int j = 0;
for (int i = 0; i < arr.length; ++i) {
   if ((Math.abs(arr[i].getX() - arr[i].getY()) > 19) {
            finalArr[j++] = arr[i];
   }
}
于 2013-01-18T21:51:56.707 に答える