[英]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.