簡體   English   中英

如何在java中將數組縮小到指定長度以保持元素均勻分布?

[英]How to Shrink array to specified length in java keeping elements uniformaly distributed?

我有源數組,我想通過從源數組中刪除指定數量的元素來從源數組中生成新數組,我希望新數組中的元素覆蓋源數組中盡可能多的元素(新元素均勻分布在源數組上),並保持第一個和最后一個元素相同(如果有)。

我嘗試了這個:

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)==>從中間(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)的兩個元素(沒問題)

removeElements(a,3)==>刪除索引(4,9,14)或(4,10,15)或(也沒有問題)的三個元素

removeElements(a,4)==>例如,刪除索引(3,7,11,15)或(3,7,11,14)的四個元素..我想要的是如果我在源數組中繪制值上(例如,在Excel上的圖表),然后從新數組中繪制值,我必須獲得同一行(或接近它)。

我認為代碼中的主要問題是您將選擇綁定到

(inputArr.length  ) / numberOfElementToDelete

這樣,您就不會考慮不想刪除的第一個和最后一個元素。

例如:如果您有一個由16個元素組成的數組,並且要刪除6個元素,則意味着最終的數組將包含10個元素,但是由於第一個和最后一個是固定的,因此您必須從中選擇8個元素剩下的14。這意味着您必須從數組中選擇8/14(0,57)個元素(不考慮第一個和最后一個)。 這意味着您可以將計數器初始化為零,從第二個數組開始掃描數組,並將分數的值求和到計數器,當計數器的值達到新的整數(例如,在第三個元素處,計數器將達到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;
    }
}

為什么你不能初始化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

如果我理解正確,這就是水庫采樣 ,即從一個大型陣列中,通過隨機選擇創建一個小型陣列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM