如何通过将同一索引下的元素分组在一起合并三个数组

2vuwiymt  于 2022-09-18  发布在  Java
关注(0)|答案(2)|浏览(166)

我有三个数组,如下所示:

int a[] = {1,2,3,4};
int b[] = {5,6,7,8};
int c[] = {9,10,11,12};

我想通过从每个数组中取第一个元素,然后取第二个元素等来合并上述数组,以获得以下结果:

int d[] = {1,5,9,2,6,10,3,7,11,4,8,12};

我尝试了以下代码,但从输出中可以看出,它将来自每个数组的数据连接起来,而不是将同一索引下的元素分组在一起。我怎样才能解决这个问题?

  • 我的代码:*
public class MergeTwoArrays2 {

    public static void main(String[] args) {
        int a[] = {1,2,3,4};
        int b[] = {5,6,7,8};
        int c[] = {9,10,11,12};

        int a1 = a.length;
        int b1 = b.length;
        int c1 = c.length;

        int d1 = a1 + b1 +c1;

        int[] d = new int[d1];

        for (int i = 0; i < a1; i = i + 1) {
            d[i] = a[i];
        }

        for (int i = 0; i < b1; i = i + 1) {
            d[a1 + i] = b[i];
        }

        for (int i = 0; i < c1; i = i + 1) {
            d[a1 + b1 + i] = c[i];
        }

        for (int i = 0; i < d1; i = i + 1) {
            System.out.println(d[i]);
        }
    }
}
  • 输出:*
[1,2,3,4,5,6,7,8,9,10,11,12]
  • 预期产出:*
[1,5,9,2,6,10,3,7,11,4,8,12]
jutyujz0

jutyujz01#

因此,您需要从所有三个数组abc中获取第一个元素,然后是第二个元素,以此类推。
为此,您需要一种不同的填充阵列d的策略。
可以同时遍历所有数组,检查下一个元素是否存在于特定数组中,如果存在,则将其分配到结果数组中的当前位置。

int[] d = new int[d1];

for (int i = 0, j = 0; i < Math.max(Math.max(a1, b1), c1);i++) {
    if (i < a1)  d[j++] = a[i];
    if (i < b1)  d[j++] = b[i];
    if (i < c1)  d[j++] = c[i];
}

System.out.println(Arrays.toString(d));
  • 输出:*
[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]

如果所有给定的数组abc都具有相同长度,则可以去掉if语句:

for (int i = 0, j = 0; i < a1; i++) {
    d[j++] = a[i];
    d[j++] = b[i];
    d[j++] = c[i];
}

概括问题

您的问题可以概括为合并具有相同长度的任意数整数数组。
这将允许消除重复语句和硬编码名称。

/**
 * Merges arbitrary number of arrays of the same length
 */
public static int[] joinAll(int[]... arrays) {
    if (arrays.length == 0) return new int[0];

    int[] result = new int[arrays.length * arrays[0].length];

    for (int i = 0, j = 0; i < arrays[0].length; i++) {
        for (int[] arr: arrays) {
            result[j++] = arr[i];
        }
    }
    return result;
}
System.out.println(Arrays.toString(joinAll(a, b, c)));
  • 输出:*
[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]

基于流的解决方案

如果您对流IPA感到满意,则可以使用一条语句表示上述广义方法的逻辑:

/**
 * Merges arbitrary number of arrays of the same length
 */
public static int[] joinAll(int[]... arrays) {
    if (arrays.length == 0) return new int[0];

    return IntStream.range(0, arrays[0].length)
        .flatMap(i -> Arrays.stream(arrays).mapToInt(arr -> arr[i]))
        .toArray();
}
a0zr77ik

a0zr77ik2#

使用java流,您可以这样做:

var aMap = IntStream.range(0, a.length)
        .boxed()
        .collect(Collectors.toMap(i -> i, i -> a[i], (x, y) -> y));

var bMap = IntStream.range(0, b.length)
        .boxed()
        .collect(Collectors.toMap(i -> i, i -> b[i], (x, y) -> y));

var cMap = IntStream.range(0, c.length)
        .boxed()
        .collect(Collectors.toMap(i -> i, i -> c[i], (x, y) -> y));

var collect = Stream.of(aMap, bMap, cMap)
        .flatMap(map -> map.entrySet().stream())
        .collect(Collectors.groupingBy(Map.Entry::getKey))
        .values().stream()
        .flatMap(Collection::stream).map(Map.Entry::getValue).toList();

相关问题