有两个方法,使用相同的数组,转换数组元素的合理公式。方法返回不同的值

时间:2018-04-18 10:32:12

标签: java arrays

有两个方法,具有相同的数组,相同的转换数组元素公式。方法返回不同的值。

数组大小:

private static final int SIZE = 10000000;
private static final int h = SIZE/2;

第一种方法: 数组填充1,用新公式计算新值

  private static float[] method1() {
    float arr[] = new float[SIZE];

        //array fill with 1,                                                        
    for (int i = 0; i < arr.length; i++) {
        arr[i] = 1;
    }


       //calulate new values with new formula                                                              
     for (int i = 0; i < arr.length; i++) {
        arr[i] = (float) (i * Math.sin(0.2f + i / 5) * 
                              Math.cos(0.2f + i / 5) * 
        Math.cos(0.4f + i / 2));

    }
     //return new value
        return arr;
}

第二种方法: Devide数组为两个,长度相同,为arr / 2, 分别计算每个的结果 编译回来一个

 private static float[] method2(){
    float arr[] = new float[SIZE];

    float firstarr[] = new float[h];

    float secondarr[] = new float[h];

    float result[] = new float[SIZE];

    for (int i = 0; i <arr.length ; i++) {
        arr[i] = 1;
    }
      //Devide array in two with same length arr/2,                                                                            
    System.arraycopy(arr, 0, firstarr, 0, h);
    System.arraycopy(arr, h, secondarr, 0, h);


    for (int i = 0; i < firstarr.length; i++) {
        firstarr[i] = (float) (i * Math.sin(0.2f + i / 5) *      
                                   Math.cos(0.2f + i / 5) *      
                                   Math.cos(0.4f + i / 2));
    }

    for (int i = 0; i < secondarr.length; i++) {
        secondarr[i] = (float) (i * Math.sin(0.2f + i / 5)                   
                                  * Math.cos(0.2f + i / 5)                   
                                  * Math.cos(0.4f + i / 2));
    }
    //compile back in one                                                                                

    System.arraycopy(firstarr, 0, result, 0, h);
    System.arraycopy(secondarr, 0, result, h, h);

    // return result
    return result;

}

Caclulate ammount array ellements

    private static long amount(float[] arr){
    long result = 0;

    for (int i = 0; i <arr.length ; i++) {
       result += arr[i];
    }
    return result;
}




public static void main(String[] args) {
    System.out.println(amount(method1()));// ammount for first method: 22527562

    System.out.println(amount(method2())); // ammount for second method: -20047478

}}

Method1的结果,而Method2应该是相同的。  哪里弄错了?为什么返回值不同?

2 个答案:

答案 0 :(得分:2)

你的问题是循环的。 第一个方法循环i从0到N.第二个方法循环从i到N / 2两次。

例如: 对于N = 4,第一种方法返回

i=0 0.0 
i=1 0.17....
i=2 0.066....
i=3 0.099....

但第二个:

i=0 0.0 
i=1 0.17....
i=0 0.0 
i=1 0.17....

所以可能的解决方案就是像这样改变第二个循环

    for (int i = h; i < SIZE; i++) {
    secondarr[i-h] = (float) (i * Math.sin(0.2f + i / 5)                   
                              * Math.cos(0.2f + i / 5)                   
                              * Math.cos(0.4f + i / 2));
}

答案 1 :(得分:1)

你在第二种方法中的问题是,你有2个相同的循环,产生相同的数组2次。 firstarr equals secondarr。打印最终数组时,这一点就变得清晰了:

方法一:

[0.0, 0.17933902, 0.066188335, 0.0992825, -0.57430935, -1.2452058, -1.9591095, -2.2856278, -0.8303678, -0.9341638, -3.0198758, -3.3218634, -5.670701, -6.1432595, -2.9212573, 0.3833428, -0.48418152, -0.51444286, -1.0486217, -1.1068785]

方法2: 两个阵列:

[0.0, 0.17933902, 0.066188335, 0.0992825, -0.57430935, -1.2452058, -1.9591095, -2.2856278, -0.8303678, -0.9341638]
[0.0, 0.17933902, 0.066188335, 0.0992825, -0.57430935, -1.2452058, -1.9591095, -2.2856278, -0.8303678, -0.9341638]

最终阵列:

[0.0, 0.17933902, 0.066188335, 0.0992825, -0.57430935, -1.2452058, -1.9591095, -2.2856278, -0.8303678, -0.9341638, 0.0, 0.17933902, 0.066188335, 0.0992825, -0.57430935, -1.2452058, -1.9591095, -2.2856278, -0.8303678, -0.9341638]

这表明您必须更改第二个for-loop以使用从h开始并继续前进的值。如果您将此for-loop用于secondarr,则会得到相同的结果:

int counter = h;
for (int i = 0; i < secondarr.length; i++) {
    secondarr[i] = (float) (counter * Math.sin(0.2f + counter / 5) * Math.cos(0.2f + counter / 5) * Math.cos(0.4f + counter / 2));
    counter++;
}

作为一点注意事项,您不需要这些for-loops中的任何一个,因为它们对您的程序没有任何作用:

for (int i = 0; i <arr.length ; i++) {
    arr[i] = 1;
}