java - 如何在保持元素均匀分布的java中将数组缩小到指定长度?

标签 java arrays algorithm

我有源数组,我想通过从源数组中删除指定数量的元素来从源数组生成新数组,我希望新数组中的元素尽可能多地覆盖源数组中的元素(新元素均匀分布在源数组中)并保持第一个和最后一个元素相同(如果有的话)。

我试过这个:

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) and removeElements(a, 4) and 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 上的图表)并从新数组中绘制值,我必须得到相同的行(或接近它)。

最佳答案

我认为您代码中的主要问题是您将选择绑定(bind)到

(inputArr.length  ) / numberOfElementToDelete

这样您就不会考虑不想删除的第一个和最后一个元素。

一个例子: 如果你有一个包含 16 个元素的数组,而你想删除 6 个元素,这意味着最终数组将有 10 个元素,但由于第一个和最后一个元素是固定的,你必须从剩余的 14 个元素中选择 8 个元素。这意味着您必须从数组中选择 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 实现(即时编写,所以我没有检查空值等)

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

关于java - 如何在保持元素均匀分布的java中将数组缩小到指定长度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11429709/

相关文章:

java - Spring Boot + Angular JS JBoss 部署

arrays - VBA:从数据表创建包含数组的数组的 .txt 文件

arrays - 如何从 K 个对象中随机挑选少于 N 个对象?

java - JavaFX 中何时隐藏舞台,如何获取?

java - Stream.peek 改变状态的可能副作用以及为什么不这样使用它

C++ MFC Serializre(CArchive &ar) 与 CArray<class*, class*>

c++ - reheapify的STL实现

algorithm - 算法中的归纳证明

php - PHP 中的深度优先迷宫生成,有人有任何示例吗?

java - 获取两个日期之间的日期列表