在不使用java中的循环的情况下添加double 数组的元素

我有一个巨大的双[] 。 (例如:例如。double double[] array = new double[] {2.0, 3.1, 4.2, 8.9, 10.11, ........}

我想一次得到该数组的所有元素的总和(不使用循环)

你有任何想法吗?

不,您无法在一个步骤中计算值列表的总和。 即使有一个API方法或某个提供sum函数的库,它也会在内部使用循环。 求和算法的复杂性是O(n)(对于单CPU)。

一个出路可能是使用并行计算,但这是一个回答你的问题的理论方法。 您至少需要与arrays单元一样多的CPU来计算步骤中的总和。 (或者一个具有与数组值一样多的FP寄存器的虚构CPU)。


在开始查看Java或其他库的API之前:

  public static double sum(double...values) { double result = 0; for (double value:values) result += value; return result; } 

用法:

  double sum = sum(array); // this is in your main code -> no loop (visible) 

是的,使用循环。 这就是他们的目的。 数百个元素对于arrays来说是一个小巧的尺寸,几乎没有时间处理。

首先,“数百”不是“巨大的”(“数百万”),其次,除非你有关于元素的一些先验信息(如果它们是特定系列的一部分),否则添加元素而不进行循环是不可能的。 。

我更喜欢以下方法。

 package rfcampusdata; public class TestClass { public static void main(String[] args) { String str = "1,2,3,4,5"; String[] arr = str.split(","); int length = arr.length; System.out.println(sum(length, arr)); } static Double temp = new Double(0); public static Double sum(int length, String[] arr) { int length_m = length - 1; String[] arr_m = arr; temp += Double.parseDouble(arr[length_m]); if (length_m != 0) { sum(length_m, arr_m); } else { // temp += Integer.parseInt(arr[0]); // System.out.println(temp); } return temp; } 

在Java 8中:

 Arrays.stream(array).sum(); 

如果你想在多个CPU上并行:

 Arrays.stream(array).parallel().sum(); 

循环是最简单,最有效的方法,例如在Java中对数组或集合的元素求和。

有一些方法可以对不涉及显式循环的数组求和,但它们涉及使用模拟的高阶函数,并且在用Java编写时它们很复杂且难看。 (并且它们很昂贵并且在引擎盖下使用循环。)

Java不是一种函数式编程语言。 如果您想/需要在Java平台上进行函数式编程,请使用Scala或Clojure。

如果你真的关心准确性,一个简单的循环可能会导致一些问题。 双打不包含任意精度。 这是一个简单的例子,展示了使用循环的缺陷。

 float f = 0; for(int i = 0; i < 1000*1000*1000; ++i){ ++f; } System.out.println(f); 

我们希望f为10亿,或1.0E9,但我们得到1.6777216E7。 这是因为浮点数只能保持大约6-7位数的精度。 双精度可以保持大约16-17位数的精度,这意味着它不太可能有问题,但它不能解决问题。

要解决这个问题,我们不需要在它们之间存在很大的差异时添加两个数字。 这可以使用PriorityQueue完成。 我们将取出前2个数字,添加它们,然后将它们放回队列中。 当队列只剩下1个号码时,我们将其返回。

 public static double queueSum(double[] da){ PriorityQueue pq = new PriorityQueue(da.length); for(double d : da) pq.add(d); while(pq.size() > 1) pq.add(pq.poll() + pq.poll()); return pq.poll(); } 

当然,准确性确实是以时间为代价的。 这从循环和的O(n)变为O(n lg(n)),更不用说所涉及对象的开销。

因为双精度比浮点数精确得多,所以你可能不需要使用它,除非你有大量的双精度(数百万/十亿)和/或你的数字之间的数量差别很大。

编辑:如果所有数字的大小大致相同,则此代码将有助于避免问题并保持O(n)时间。 如果两个样本之间存在较大的幅度差异,或者数字以可能导致较大幅度差异的方式分布,则可能会遇到与之前相同的问题。

 public static double treeSum(double[] da){ double[] dc = da.clone(); int len = dc.length; while(len > 1){ len = (len + 1) / 2; for(int i = 0; i < len; ++i) dc[i] += dc[i + len]; dc[len] = 0; } return dc[0]; } 

如果您的数组已分配给cern.colt.matrix库中的DoubleMatrix1D对象,则可以使用zSum()方法,它将返回数组中所有元素的总和,而不必循环

your_sum = your_array.zSum()

如果数组中的数据类型是对象类型Double ,而不是基本类型double ,那么你可以在java 8中使用stream ,如下所示:

 Double[] test = new Double[] {2.0, 3.1, 4.2, 8.9, 10.11}; List list = Arrays.asList(test); double sum = list.stream().mapToDouble(p -> p).sum(); System.out.println(sum); 

任何拥有大量双打的人都可以查找cern.colt.list.AbstractDoubleList,它是为了优化添加(元素)等操作而构建的。

正如其他人所说,如果你想要数组中所有元素的总和,你应该写一个循环。

循环是最简单的方法,但是因为你要求另一个:

递归:

 double sumResult = sum(data, 0, 0); double sum(double [] d, int sum, int index) { if ( index > d.length ) return sum; else return sum(d, sum + d[index], index+1); } 

我没有测试过,但它应该在上面的某个地方工作。

编辑:不建议使用这样的构造,因为对于大型数组,您可能会非常快速地触及StackOverflowException。

您需要在函数内部创建一个嵌套类,并在嵌套类中使用递归来执行添加:

 public double sumArrayNoLoop(double[] v){ class compute { double total = 0.0; public void sumArray(double[] v,int offset){ if((offset - 1) < 0) return; if(offset > (v.length - 1)) offset = v.length; total += v[offset - 1]; sumArray(v,offset - 1); } } compute c = new compute(); c.sumArray(v, v.length); return c.total; } 

一世

朋友这是我完成的完美解决方案。我正在用字符串处理复杂的情况。 我们可以直接使用双数组。

 public class TestClass { public static void main(String[] args) { String str = "1,2,3,4,5"; String[] arr = str.split(","); int length = arr.length; System.out.println(sum(length, arr)); } static Double temp = new Double(0); public static Double sum(int length, String[] arr) { int length_m = length - 1; String[] arr_m = arr; temp += Double.parseDouble(arr[length_m]); if (length_m != 0) { sum(length_m, arr_m); } else { // temp += Integer.parseInt(arr[0]); // System.out.println(temp); } return temp; } 

美好的一天!!!!