简体   繁体   中英

Folding an integer array in half

I am working on a method that will take an integer array and fold it in half x number of times. This method would take an integer array like this {1,2,3,4,5} and output an the array {6,6,3} if it is folded once. Or it could take the input {5,6,7,8} and output {13,13} also folded once.

If the input is folded twice then {5,6,7,8} would turn into {26}.

import java.util.Arrays;
public class Kata
{
  public static int[] foldArray(int[] array, int runs)
  { 
    int[] tempArray = array;

    for(int j=0; j<runs; j++){
      for(int i=0; i<tempArray.length; i++){
        tempArray[i] += tempArray[tempArray.length - i];
      }
    }

    int[] outputArray = Arrays.copyOfRange(tempArray, (tempArray.length/2));
    return outputArray;
  } 
}

The problem with your implementation is the way in which you use tempArray :

int[] tempArray = array;

This "aliases" tempArray to the original array , so any modifications to tempArray also happen to the original array. This means that tempArray 's length is not going to change from run to run, so any fold after the first one would be invalid.

You need to make tempArray a copy of the initial ⌈n/2⌉ elements on each iteration of the outer loop. To round half-length up, use this expression:

int halfLength = (tempArray.length+1)/2;
int[] tempArray = Arrays.copyOfRange(tempArray, halfLength);

This will deal with arrays of odd length.

At the end of each outer loop iteration replace array with tempArray .

You can also solve your problem recursively:

public static int[] foldArray(int[] array, int runs) {

    if (runs == 0) {
        return array;
    }

    int[] tmp;
    if (array.length % 2 == 0) {
        tmp = new int[array.length / 2];
        for (int i = 0; i < array.length / 2; i++) {
            tmp[i] = array[i];
        }
    } else {
        tmp = new int[array.length / 2 + 1];
        for (int i = 0; i < array.length / 2 + 1; i++) {
            tmp[i] = array[i];
        }
    }

    for (int i = 0; i < array.length / 2; i++) {
        tmp[i] += array[array.length - i - 1];
    }
    return foldArray(tmp, runs - 1);

}

public static void main(String[] args) {
    System.out.println(Arrays.toString(foldArray(new int[]{1, 2, 3, 4, 5}, 1)));
    System.out.println(Arrays.toString(foldArray(new int[]{5, 6, 7, 8}, 1)));
    System.out.println(Arrays.toString(foldArray(new int[]{5, 6, 7, 8}, 2)));
}

Note that you need to be careful with the length of the input arrays - whether it's odd or even.

Solution in JavaScript :

function fold(arr, num) {
    if (num === 0 || arr.length === 1) {
        return arr;
    }
    let result = [];
    while (arr.length > 1) {
        result.push(arr.shift() + arr.pop());
    }
    if(arr.length === 1){
    result.push(arr[0]);
    }
    return fold(result, num - 1);
}

Example:

const arr = [1, 2, 3, 4, 5];

fold(arr, 2);  --> [9,6]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM