1

ソース配列があり、ソース配列から指定された数の要素を削除してソース配列から新しい配列を生成したいのですが、新しい配列の要素がソース配列の要素をできるだけ多くカバーするようにしたいです (新しい要素はソース配列全体に均一に分散されます)、最初と最後の要素を同じに保ちます (存在する場合)。

私はこれを試しました:

public static void printArr(float[] arr)
    {
        for (int i = 0; i < arr.length; i++)
            System.out.println("arr[" + i + "]=" + arr[i]);

    }
public static float[] removeElements(float[] inputArr , int numberOfElementToDelete)
    {
       float [] new_arr = new float[inputArr.length - numberOfElementToDelete];
        int f = (inputArr.length  ) / numberOfElementToDelete;
        System.out.println("f=" + f);
        if(f == 1)
        {
            f = 2;
            System.out.println("f=" + f);
        }

       int j = 1 ;
        for (int i = 1; i < inputArr.length ; i++)
        {
            if( (i + 1) % f != 0)
            {

                System.out.println("i=" + i + "   j= " + j);
                if(j < new_arr.length)
                {
                    new_arr[j] = inputArr[i];
                    j++;
                }

            }

        }

        new_arr[0] = inputArr[0];
        new_arr[new_arr.length - 1] = inputArr[inputArr.length - 1];
        return new_arr;
    }
public static void main(String[] args)
    {

        float [] a = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
        a = removeElements(a, 6);
        printArr(a);
    }

私は(removeElements(a、5)とremoveElements(a、4)とremoveElements(a、3))のテストを行いましたが、removeElements(a、6); 与えた:

 arr[0]=1.0
arr[1]=3.0
arr[2]=5.0
arr[3]=7.0
arr[4]=9.0
arr[5]=11.0
arr[6]=13.0
arr[7]=15.0
arr[8]=0.0
arr[9]=16.0

問題は (arr[8]=0.0) 値を取る必要があります..これを解決するにはどうすればよいですか? 指定された数の要素を削除できるコードはありますか (そして、一部の要素でゼロを生成することなく、要素をソース配列全体に分散させたままにします)?

編集 :

例 : removeElements(a, 1) ==> 中央から 1 つの要素を削除 (7) {1,2,3,4,5,6,7,9,10,11,12,13,14,15,16 }

removeElements(a, 2) ==> インデックス (4,19) または (5,10) または (4,10) の 2 つの要素を削除します (問題ありません)

removeElements(a, 3) ==> インデックス (4,9,14) または (4,10, 15) または (これも問題ありません) の 3 つの要素を削除します

removeElements(a, 4) ==> インデックス (3,7,11 , 15) または ( 3 ,7,11,14) の 4 つの要素を削除します。たとえば、ソース配列に値を描画する場合に必要です。 on (たとえば、Excel のグラフ) で、新しい配列から値を描画します。同じ線 (またはそれに近い線) を取得する必要があります。

4

3 に答える 3

1

コードの主な問題は、選択範囲をにバインドしていることだと思います

(inputArr.length  ) / numberOfElementToDelete

このようにして、削除したくない最初と最後の要素を考慮していません。

例:16個の要素の配列があり、6個の要素を削除する場合は、最終的な配列に10個の要素が含まれることを意味しますが、最初と最後が固定されているため、から8個の要素を選択する必要があります。残りの14。これは、配列から8/14(0,57)要素を選択する必要があることを意味します(最初と最後を考慮しません)。これは、カウンターの値が新しい整数に達したときに、カウンターをゼロに初期化し、2番目から配列をスキャンし、小数部の値をカウンターに合計できることを意味します(たとえば、3番目の要素でカウンターは1,14に到達)新しい配列に選択して配置する要素があります。

したがって、次のようなことができます(擬似コード):

    int newLength = originalLength - toDelete;
    int toChoose = newLength - 2;
    double fraction = toChoose / (originalLength -2)
    double counter = 0;
    int threshold = 1;
    int newArrayIndex = 1;
    for(int i = 1; i < originalLength-1; i++){
        **counter += fraction;**            
        if(integerValueOf(counter) == threshold){
            newArray[newArrayIndex] = originalArray[i];
            threshold++;
            **newArrayIndex++;**
        }

     }
     newArray[0] = originalArray[0];
     newArray[newArray.length-1] = originalArray[originalArray.length-1];

長さ1のoriginalArrayやすべての要素の削除などの特定のケースを確認する必要がありますが、機能するはずです。

編集 これはJavaの実装です(その場で書かれているので、nullなどをチェックしませんでした)

public class Test {

    public static void main(String[] args){
        int[] testArray = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
        int[] newArray = remove(testArray, 6);
        for(int i = 0; i < newArray.length; i++){
            System.out.print(newArray[i]+" ");
        }
    }

    public static int[] remove(int[] originalArray, int toDelete){  
        if(toDelete == originalArray.length){
            //avoid the removal of all the elements, save at least first and last
            toDelete = originalArray.length-2;
        }
        int originalLength = originalArray.length;
        int newLength = originalLength - toDelete;
        int toChoose = newLength - 2;
        int[] newArray = new int[newLength];
        double fraction = ((double)toChoose) / ((double)originalLength -2);
        double counter = 0;
        int threshold = 1;
        int newArrayIndex = 1;
        for(int i = 1; i < originalLength-1; i++){
            counter += fraction;            
            if(((int)counter) == threshold ||
                //condition added to cope with x.99999999999999999... cases 
               (i == originalLength-2 && newArrayIndex == newLength-2)){
                newArray[newArrayIndex] = originalArray[i];
                threshold++;
                newArrayIndex++;
            }           
         }
         newArray[0] = originalArray[0];
         newArray[newArray.length-1] = originalArray[originalArray.length-1];
         return newArray;
    }
}
于 2012-07-11T10:23:26.107 に答える
0

私が正しく理解している場合、これは貯水池サンプリングです。つまり、大きな配列から、ランダムに選択して小さな配列を作成します。

于 2012-07-11T10:05:36.613 に答える
0

なぜ初期化できないのかi=0

for (int i = 0; i < inputArr.length; i++) {
        if ((i + 1) % f != 0) {

出力は次のとおりです。

arr[0]=1.0
arr[1]=1.0
arr[2]=3.0
arr[3]=5.0
arr[4]=7.0
arr[5]=9.0
arr[6]=11.0
arr[7]=13.0
arr[8]=15.0
arr[9]=16.0
于 2012-07-11T09:51:12.460 に答える