Home > Software engineering >  Summing arrayelements up with init, elements, steps
Summing arrayelements up with init, elements, steps

Time:03-20

Hi Im searching a fast dynamic programming / formula solution. For following algorithm, example:

init := 1

elements := 4

steps := 3

step 1. [1,1,1,1] init is placed in each index

step 2. [1,2,3] index i is calculated by sum of former step index 0 until inclusive step 1 index i, arraysize get's decremented by one.

step 3. [1,3] Same procedere like step 2 but using step 2 as base.

final step solution := 4 final step is summing up last stepelements.

Is there a faster way than summing up manually?

Sample Code:

long calc(int init,int elements,int steps){
  int[] dp1 = new int[elements-1];
  Arrays.fill(dp1, init);
  int[] dp2 = new int[elements-1];

  for(int i = 0; i < steps-1; i  ){
    for(int j = 0,cur = 0; j < elements-i-1; j  ){
      dp2[j] = cur = cur   dp1[j];
    }
    System.arraycopy(dp2,0,dp1,0,elements-i-1);
    Arrays.fill(dp2, 0);
  }
  return Arrays.stream(Arrays.copyOf(dp1,elements-steps 1)).sum();
}

CodePudding user response:

You're doing a lot of copying and filling where none is necessary. Try it like this.

static long myCalc(int init, int elements, int steps) {
    if (steps > elements 1) {
        System.out.println("Steps too large for # of elements");
        return -1;
    }
    int[] dp1 = new int[elements - 1];
    Arrays.fill(dp1, init);
    int len = dp1.length;
    for (int j = 0; j < steps - 1; j  ) {
        for (int i = 1; i < len; i  ) {
            dp1[i] = dp1[i - 1]   dp1[i];
        }
        len--;
    }
    return Arrays.stream(dp1).limit(len 1).sum();
}

Added improvement. For each step, one less value is added. So adjust the for loop iterations to accommodate.

CodePudding user response:

You might want to look at the Arrays.parallelPrefix method. From the java doc:

Cumulates, in parallel, each element of the given array in place, using the supplied function. For example if the array initially holds [2, 1, 0, 3] and the operation performs addition, then upon return the array holds [2, 3, 3, 6]. Parallel prefix computation is usually more efficient than sequential loops for large arrays.

So something like below might be what you are looking for :

long calc(int init,int elements,int steps){
    int[] arr = new int[elements];
    Arrays.fill(arr,init);

    int[] curr = arr;
    for (int i = 1; i < steps; i  ){
        Arrays.parallelPrefix(curr, Integer::sum);
        curr = Arrays.copyOf(curr,curr.length-1);
        System.out.println(Arrays.toString(curr)); // just to check the sub steps, remove if I get the discription of the steps right
    }
    return Arrays.stream(curr).sum();
}
  • Related