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

时间:2021-08-06 09:47:02

I have a double[] of huge size. (Ex : Eg.double[] array = new double[] {2.0, 3.1, 4.2, 8.9, 10.11, ........})

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

I want to get the sum of all the elements of that array at once. (Without using a loop).

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

Do you have any idea to do this?

你有任何想法吗?

13 个解决方案

#1


10  

No, you can't calculate the sum of a list of values in one step. Even if there was an API method or some library that offered a sum function, it would use loops internally. The complexity of the sum algorithm is O(n) (for single CPUs).

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

A way out could be using parallel computing, but that's a theoretical approach to answer your question. You'd need at least as many CPUs as array cells to calculate the sum in on step. (Or one fictional CPU with as many FP registers as array values).

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


Before you start looking at API's of Java or other libraries:

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

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

Usage:

用法:

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

#2


9  

Yes, use a loop. That's what they're for. Hundreds of elements is a piddling little size for an array and will take almost no time to process.

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

#3


4  

First of all, 'hundreds' is not 'huge' ('millions' is) and second, adding the elements without looping is not possible unless you have some prior information about the elements (like if they are a part of a particular series).

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

#4


3  

I would prefer the following approach.

我更喜欢以下方法。

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;

  }

#5


3  

In Java 8:

在Java 8中:

Arrays.stream(array).sum();

And if you want parallel on multiple CPUs:

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

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

#6


2  

A loop is the simplest and most efficient way to do things like summing the elements of an array or collection in Java.

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

There are ways to sum arrays that don't involve explicit loops, but they involve using simulated higher order functions, and they are complicated and ugly when written in Java. (And they are expensive and use loops under the hood.)

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

Java is not a functional programming language. If you want / need to do functional programming on the Java platform, use Scala or Clojure.

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

#7


2  

If you're really concerned with accuracy, a simple loop might cause some problems. Doubles do not contain arbitrary precision. Here's a simple example to show the flaw of just using a loop.

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

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

We would hope that f would be 1 billion, or 1.0E9, but instead we get 1.6777216E7. This is because the float can only hold about 6-7 digits of precision. A double can hold about 16-17 digits of precision which means it is less likely to have an issue, but it doesn't solve the problem.

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

To work around this, we need to not add two numbers when there is a large magnitude difference between them. This can simply be done using a PriorityQueue. We'll take out the first 2 numbers, add them, then put them back into the queue. When the queue only has 1 number left, we return it.

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

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

Of course accuracy does come at the cost of time. This goes from the loop sum's O(n) to a O(n lg(n)) not to mention the overhead of the objects involved.

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

Because doubles have much more precision than a float, you probably won't need to use this unless you have a huge number of doubles (millions/billions) and/or you have a large difference in magnitudes between your numbers.

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

Edit: If all the numbers have approximately the same magnitude, this code will help avoid the problem as well as maintain O(n) time. If there is a large magnitude difference between two samples or the numbers are distributed in a fashion that could cause a large magnitude difference, it could suffer the same problems as before.

编辑:如果所有数字的大小大致相同,则此代码将有助于避免问题并保持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];
}

#8


2  

If your array is assigned to a DoubleMatrix1D object in cern.colt.matrix library you can use the zSum() method and it will return the sum of all elements in your array without having to loop

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

your_sum=your_array.zSum()

your_sum = your_array.zSum()

#9


2  

if the data type in your array is the object type Double ,not the primitive type double,then you can use stream in java 8 like this:

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

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

#10


1  

Anyone who has an actually huge array of doubles might look up cern.colt.list.AbstractDoubleList, which is built to optimize operations like adding (elements).

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

As others have said, if you want the summation of all elements in your array, you should write a loop.

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

#11


1  

Looping is the simplest way for this, but since you asked for a different one:

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

Recursion:

递归:

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

I haven't tested that, but it should work somewhere along the above.

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

EDIT: It is not recommended to use such a construct, since for huge array you may hit the *Exception very fast.

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

#12


1  

You need to create a nested class inside of the function and use recursion inside of the nested class to do the addition:

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

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

I

一世

#13


1  

Friends this is the perfect solution that i have done.I am taking complex condition with string. we can used directly double array.

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

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;

  }

good day!!!!

美好的一天!!!!

#1


10  

No, you can't calculate the sum of a list of values in one step. Even if there was an API method or some library that offered a sum function, it would use loops internally. The complexity of the sum algorithm is O(n) (for single CPUs).

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

A way out could be using parallel computing, but that's a theoretical approach to answer your question. You'd need at least as many CPUs as array cells to calculate the sum in on step. (Or one fictional CPU with as many FP registers as array values).

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


Before you start looking at API's of Java or other libraries:

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

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

Usage:

用法:

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

#2


9  

Yes, use a loop. That's what they're for. Hundreds of elements is a piddling little size for an array and will take almost no time to process.

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

#3


4  

First of all, 'hundreds' is not 'huge' ('millions' is) and second, adding the elements without looping is not possible unless you have some prior information about the elements (like if they are a part of a particular series).

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

#4


3  

I would prefer the following approach.

我更喜欢以下方法。

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;

  }

#5


3  

In Java 8:

在Java 8中:

Arrays.stream(array).sum();

And if you want parallel on multiple CPUs:

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

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

#6


2  

A loop is the simplest and most efficient way to do things like summing the elements of an array or collection in Java.

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

There are ways to sum arrays that don't involve explicit loops, but they involve using simulated higher order functions, and they are complicated and ugly when written in Java. (And they are expensive and use loops under the hood.)

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

Java is not a functional programming language. If you want / need to do functional programming on the Java platform, use Scala or Clojure.

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

#7


2  

If you're really concerned with accuracy, a simple loop might cause some problems. Doubles do not contain arbitrary precision. Here's a simple example to show the flaw of just using a loop.

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

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

We would hope that f would be 1 billion, or 1.0E9, but instead we get 1.6777216E7. This is because the float can only hold about 6-7 digits of precision. A double can hold about 16-17 digits of precision which means it is less likely to have an issue, but it doesn't solve the problem.

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

To work around this, we need to not add two numbers when there is a large magnitude difference between them. This can simply be done using a PriorityQueue. We'll take out the first 2 numbers, add them, then put them back into the queue. When the queue only has 1 number left, we return it.

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

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

Of course accuracy does come at the cost of time. This goes from the loop sum's O(n) to a O(n lg(n)) not to mention the overhead of the objects involved.

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

Because doubles have much more precision than a float, you probably won't need to use this unless you have a huge number of doubles (millions/billions) and/or you have a large difference in magnitudes between your numbers.

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

Edit: If all the numbers have approximately the same magnitude, this code will help avoid the problem as well as maintain O(n) time. If there is a large magnitude difference between two samples or the numbers are distributed in a fashion that could cause a large magnitude difference, it could suffer the same problems as before.

编辑:如果所有数字的大小大致相同,则此代码将有助于避免问题并保持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];
}

#8


2  

If your array is assigned to a DoubleMatrix1D object in cern.colt.matrix library you can use the zSum() method and it will return the sum of all elements in your array without having to loop

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

your_sum=your_array.zSum()

your_sum = your_array.zSum()

#9


2  

if the data type in your array is the object type Double ,not the primitive type double,then you can use stream in java 8 like this:

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

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

#10


1  

Anyone who has an actually huge array of doubles might look up cern.colt.list.AbstractDoubleList, which is built to optimize operations like adding (elements).

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

As others have said, if you want the summation of all elements in your array, you should write a loop.

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

#11


1  

Looping is the simplest way for this, but since you asked for a different one:

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

Recursion:

递归:

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

I haven't tested that, but it should work somewhere along the above.

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

EDIT: It is not recommended to use such a construct, since for huge array you may hit the *Exception very fast.

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

#12


1  

You need to create a nested class inside of the function and use recursion inside of the nested class to do the addition:

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

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

I

一世

#13


1  

Friends this is the perfect solution that i have done.I am taking complex condition with string. we can used directly double array.

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

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;

  }

good day!!!!

美好的一天!!!!