我有一个巨大的 double [] 。 (例如:double[] array = new double[] {2.0, 3.1, 4.2, 8.9, 10.11, ........}
)
我希望一次获得该数组的所有元素的总和。 (不使用循环)。
你有任何想法吗?
答案 0 :(得分:10)
不,您无法在一个步骤中计算值列表的总和。即使有一个API方法或某个提供sum函数的库,它也会在内部使用循环。求和算法的复杂性为O(n)(对于单CPU)。
出路可能是使用并行计算,但这是回答你的问题的理论方法。您至少需要与阵列单元一样多的CPU来计算步骤中的总和。 (或者一个虚构的CPU,其FP寄存器数量与数组值一样多)。
在开始查看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)
答案 1 :(得分:9)
是的,使用循环。这就是他们的目的。数百个元素对于数组来说是一个小巧的大小,几乎没有时间处理。
答案 2 :(得分:4)
首先,“数百”不是“巨大的”(“数百万”),其次,除非你有一些关于元素的先验信息(如果它们是一部分的话),那么添加元素而不进行循环是不可能的。特别系列)。
答案 3 :(得分:4)
在Java 8中:
Arrays.stream(array).sum();
如果你想在多个CPU上并行:
Arrays.stream(array).parallel().sum();
答案 4 :(得分:3)
我更喜欢以下方法。
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 :(得分:2)
循环是最简单,最有效的方法,例如在Java中对数组或集合的元素求和。
有些方法可以对不涉及显式循环的数组进行求和,但它们涉及使用模拟高阶函数,并且在用Java编写时它们很复杂且难看。 (而且它们很昂贵并且在引擎盖下使用循环。)
Java不是一种函数式编程语言。如果您希望/需要在Java平台上进行函数式编程,请使用Scala或Clojure。
答案 6 :(得分:2)
如果你真的关心准确性,一个简单的循环可能会导致一些问题。双打不包含任意精度。这是一个简单的例子,展示了使用循环的缺陷。
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完成。我们将取出前两个数字,添加它们,然后将它们放回队列中。当队列只剩下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();
}
当然,准确性确实是以时间为代价的。这从循环和的O(n)变为O(n lg(n)),更不用说所涉及对象的开销。
因为双精度比浮点数精确得多,所以你可能不需要使用它,除非你有大量的双精度数(数百万/十亿)和/或你的数字之间的数量差别很大。 / p>
编辑: 如果所有数字的大小大致相同,则此代码将有助于避免问题并保持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];
}
答案 7 :(得分:2)
如果您的数组已分配给cern.colt.matrix库中的DoubleMatrix1D对象,则可以使用zSum()方法,它将返回数组中所有元素的总和而无需循环
your_sum = your_array.zSum()
答案 8 :(得分:2)
如果数组中的数据类型是对象类型 Double ,而不是基本类型 double ,那么您可以在<流中使用流 strong> java 8 像这样:
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);
答案 9 :(得分:1)
任何拥有大量双打的人都可以查找cern.colt.list.AbstractDoubleList,它是为了优化添加(元素)等操作而构建的。
正如其他人所说,如果你想要数组中所有元素的总和,你应该写一个循环。
答案 10 :(得分:1)
循环是最简单的方法,但是因为你要求另一个:
递归:
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。
答案 11 :(得分:1)
你需要在函数内部创建一个嵌套类,并在嵌套类中使用递归来进行添加:
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;
}
我
答案 12 :(得分:1)
朋友这是我完成的完美解决方案。我正在用字符串处理复杂的情况。我们可以直接使用双数组。
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;
}
美好的一天!!!!