简体   繁体   中英

How to fill an array with elements from another array of different size? (leaving non existent indexes as zero)

SCENARIO 1: if main array length is < 8

Declaration:

int[] mainArray = new int[] { 1, 2, 3, 4, 5 } // no minimum number of elements
int[] arrayOne = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }; // must have 8 elements

I want to add the values from mainArray into arrayOne, with the spare elements being left as zero.

Desired array :

int[] arrayOne = new int[] { 1, 2, 3, 4, 5, 0, 0, 0 }; // must have 8 elements

SCENARIO 2: if main array length is > 8

Declaration:

int[] mainArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } // no minimum number of elements
int[] arrayOne = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }; // must have 8 elements
int[] arrayTwo = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 }; // must have 8 elements

I want to add the the first 8 values from mainArray into arrayOne, and then the remaining values in arrayTwo, leaving the other indexes as zero (you'll see the 9 and 10 on the right of the second array, so arrayOne is left to right, arrayTwo is right to left. If there was an arrayThree, that would be left to right again)

Desired arrays:

int[] arrayOne = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }; // must have 8 elements
int[] arrayTwo = new int[] { 0, 0, 0, 0, 0, 0, 10, 9 }; // must have 8 elements

You can use

        Arrays.fill(arr, 0);

for your subsequent arrays, you can start from end index - length of remaining entries modulo 8 to arrive at how many other arrays you have to fill.

First off, I'm assuming that you made your Array initializations like that for the sake of the demonstration. If not, you can just create any custom array like this: int[] arrayOne = {n, n, n, n, n, n}; (Using any number of elements separated by commas in between the curly brackets)

To achieve what you want to do, you would need to use a bunch of loops. This is how I would solve it:

if (mainArray.length <= 8) {
    for (int i = 0; i < mainArray.length; i++) {
        arrayOne[i] = mainArray[i];
    } // very standard loop for copying and pasting elements
} else {
    int direction = 1; // 1 means left to right, -1 means right to left
    int shortIndex = 0; // modified as to return back to index zero when equal to 8    
    for (int i = 0; i < mainArray.length; i++) {
        if (i + 1 % 8 == 0 && i != 0) { // switching directions when length 8 is reached
            direction *= -1;
        }

        if (direction == 1) {
            ArrayOne[shortIndex] = mainArray[i];
            shortIndex++;
        } else if (direction == -1) {
            ArrayTwo[shortIndex] = mainArray[I];
            shortIndex--;
        }
    }
}

This is really just me sketching out a basic idea as I haven't actually tested this code but I hope this gives you a better understanding of how you would solve it. Also this would probably only work if you only need two arrays as opposed to 3 or more.

Basically if the mainArray length is greater than 8 you will need an additional counter variable as well as some sort of variable that switches condition when arrayOne has hit its max and is ready to move on to the next one. When this happens, I switch the conditional variable (direction) so that my loop knows which direction to iterate through the arrays.

shortIndex is the second counter variable I was talking about. It will follow variable 'i' counting up by 1 each iteration until index 7 is reached (same as length 8), and then once the direction has changed it will begin at index 7 (again, same as length 8) and count down from there.

I hope this explanation wasn't too confusing lol

For this I use a List<int[]> to store the arrays. It iterates over the mainArray and successively copies the contents as specified until no more elements are left. It alternately reversed sublists of the List.

mainArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
                13, 14 }; // no minimum number of elements

List<int[]> arrays = new ArrayList<>();
int size = 5;
int begin = 0;
// Copy the array, rounding up to a multiple of size, filling in with 0 value.
mainArray = Arrays.copyOf(mainArray, mainArray.length + (size - (mainArray.length % size)));

// convert the mainArray to a list.  Need this to use subList and reverse.
List<Integer> vals = IntStream.of(mainArray).boxed().collect(Collectors.toList());

boolean reverse = false;
while (begin < vals.size()) {
    // get the first group of numbers, going from left to right.
    List<Integer> sublist = vals.subList(begin,begin+size);
    // check if time to reverse the sublist.
    if (reverse) {
        Collections.reverse(sublist);
    }
    // now just copy the sublist to an array and store away.
    arrays.add(sublist.stream().mapToInt(Integer::intValue).toArray());
    // update state
    reverse = !reverse;
    begin+=size;
}
    
for (int[] a : arrays) {
    System.out.println(Arrays.toString(a));
}

Prints for size = 5

[1, 2, 3, 4, 5]
[10, 9, 8, 7, 6]
[11, 12, 13, 14, 0]

For size = 8

[1, 2, 3, 4, 5, 6, 7, 8]
[0, 0, 14, 13, 12, 11, 10, 9]

Here's another method that only uses a List to return the constructed arrays. It simply changes the fill direction every other iteration.

public static List<int[]> fill(int[] main, int size) {
    List<int[]> arrays = new ArrayList<>();
    main = Arrays.copyOf(main,
            main.length + (size - (main.length % size)));
    int count = (main.length/size)+1;
    int ainc = 0;
    while (count-- > 1) {
        int[] temp = new int[size];
        arrays.add(temp);
        boolean reverse = count % 2 == 0;
        int idx = reverse ? size - 1 : 0;
        int inc = reverse ? -1 : 1;
        
        for (int i = 0; i < size; i++) {
            temp[idx] = main[ainc++];
            idx += inc;
        }
    }
    return arrays;
}

Try this.

static int copy(int[] mainArray, int start, int[] array) {
    int mainArrayLength = mainArray.length;
    if (start >= mainArrayLength) return start;
    int length = Math.min(mainArrayLength - start, array.length);
    System.arraycopy(mainArray, start, array, 0, length);
    return start + length;
}

static void reverse(int[] array) {
    for (int i = 0, j = array.length - 1; i < j; ++i, --j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

static void copy(int[] mainArray, int[] arrayOne, int[] arrayTwo) {
    int start = copy(mainArray, 0, arrayOne);
    copy(mainArray, start, arrayTwo);
    reverse(arrayTwo);
}

and

    int[] mainArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int[] arrayOne = {0, 0, 0, 0, 0, 0, 0, 0};
    int[] arrayTwo = {0, 0, 0, 0, 0, 0, 0, 0};
    copy(mainArray, arrayOne, arrayTwo);
    System.out.println("arrayOne = " + Arrays.toString(arrayOne));
    System.out.println("arrayTwo = " + Arrays.toString(arrayTwo));

output

arrayOne = [1, 2, 3, 4, 5, 6, 7, 8]
arrayTwo = [0, 0, 0, 0, 0, 0, 10, 9]

Do this if you want to copy to more than two arrays without reversing them.

static void copy(int[] mainArray, int[]... arrays) {
    int start = 0;
    for (int[] array : arrays)
        start = copy(mainArray, start, array);
}

and

int[] mainArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
int[] arrayOne = {0, 0, 0, 0, 0};
int[] arrayTwo = {0, 0, 0, 0, 0};
int[] arrayThree = {0, 0, 0, 0, 0};
copy(mainArray, arrayOne, arrayTwo, arrayThree);
System.out.println("arrayOne = " + Arrays.toString(arrayOne));
System.out.println("arrayTwo = " + Arrays.toString(arrayTwo));
System.out.println("arrayThree = " + Arrays.toString(arrayThree));

output

arrayOne = [1, 2, 3, 4, 5]
arrayTwo = [6, 7, 8, 9, 10]
arrayThree = [11, 12, 13, 0, 0]

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