当前位置: 首页 > 知识库问答 >
问题:

如何在Java中获得两个n维数组的总和?

陈德泽
2023-03-14

Java中的两个一维数组/向量可以这样相加:

public static int[] addVectors( int[] a, int[] b )
{
    int[] c = new int[a.length];

    for ( int i = 0; i < a.length; i++ )
    {
        c[i] = a[i] + b[i];
    }

    return c;
}

Java中的两个二维数组/矩阵可以这样添加:

public static int[][] addMatrices( int[][] a, int[][] b )
{
    int[][] c = new int[a.length][a[0].length];

    for ( int i = 0; i < a.length; i++ )
    {
        c[i] = addVectors( a[i], b[i] );
    }

    return c;
}

这两个函数都要求数组具有相同的大小,以避免arrayOutOfBoundsException

应该有一种方法可以使用递归添加两个未知维度的数组。
例如,下面的代码使用假设函数addArraysN(arr1, arr2)

int[][][] a = { 
                { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } },
                { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } },
                { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } }
              };
int[][][] b = { 
                { { 2, 2, 2 }, { 2, 2, 2 }, { 2, 2, 2 } },
                { { 2, 2, 2 }, { 2, 2, 2 }, { 2, 2, 2 } },
                { { 2, 2, 2 }, { 2, 2, 2 }, { 2, 2, 2 } }
              };
int[][][] sum = addArraysN( a, b );
System.out.println( java.util.Arrays.deepToString( sum ) );

应该输出

[[[3, 3, 3], [3, 3, 3], [3, 3, 3]], [[3, 3, 3], [3, 3, 3], [3, 3, 3]], [[3, 3, 3], [3, 3, 3], [3, 3, 3]]]

现在我想知道如何实现这个函数添加数组N(arr1,arr2)
我从以下伪代码开始:

addArraysN( arr1, arr2 )
{
    int dimension = getDimension( arr1 );
    if ( dimension == 0 ) //there are no arrays, only numbers
        return arr1 + arr2;
    else
    {
        //create a new arrays with the same dimension and size as arr1 / arr2
        //loop through the fields with for
            //call itself when adding the fields of arr1 and arr2
        //return the sum
    }
}

可以使用java.lang.reflect.Array中的newInstance-方法创建新数组
可以这样进行循环

for ( int i = 0; i < ((int[])arr1).length; i++ )
    sum = addArraysN( ((int[])arr1)[i], ((int[])arr2)[i] );

但我遇到了很多运行时错误和其他问题。关于如何实现这个addArrayN-方法,有人有想法甚至有解决方案吗?

也应该可以使用 ArrayList 或任何其他类,但我主要对如何使用数组执行此操作感兴趣...(但是,如果有人知道它,请发布!

预先感谢

我的原始代码:

import java.util.Arrays;
import java.lang.reflect.Array;

public class ArrayN
{
    public static void main( String[] args )
    {
        //Vector
        int[] vector1 = {0, 1, 2, 3, 4};
        int[] vector2 = {4, 3, 2, 1, 0};

        int[] vector3 = ArrayN.addVectors( vector1, vector2 );

        for ( int num : vector3 )
        {
            System.out.print( num );
        }
        System.out.println();

        System.out.println();

        //Matrix
        int[][] matrix1 = {{0, 1, 2, 3, 4}, {4, 3, 2, 1, 0}};
        int[][] matrix2 = {{4, 3, 2, 1, 0}, {0, 1, 2, 3, 4}};

        int[][] matrix3 = ArrayN.addMatrices( matrix1, matrix2 );

        for ( int[] vector : matrix3 )
        {
            for ( int num : vector )
            {
                System.out.print( num );
            }
            System.out.println();
        }

        System.out.println();

        //N-Array

        System.out.println( Arrays.deepToString( (Object[])ArrayN.addArraysN( (Object)matrix1, (Object)matrix2, 2, 5 ) ) );

    }

    public static int[] addVectors( int[] a, int[] b )
    {
        int[] c = new int[a.length];

        for ( int i = 0; i < a.length; i++ )
        {
            c[i] = a[i] + b[i];
        }

        return c;
    }

    public static int[][] addMatrices( int[][] a, int[][] b )
    {
        int[][] c = new int[a.length][a[0].length];

        for ( int i = 0; i < a.length; i++ )
        {
            c[i] = ArrayN.addVectors( a[i], b[i] );
        }

        return c;
    }

    public static Object addArraysN( Object arrayN1, Object arrayN2, int dimension, int innerlength )
    {
        if ( dimension == 0 )
        {
            return (int)arrayN1 + (int)arrayN2;
        }
        else
        {
            int[] dimensions = new int[dimension];
            for ( int i = 0; i < dimension; i++ )
            {
                dimensions[i] = innerlength;
            }
            Object arrayN3 = Array.newInstance( Array.class, dimensions );
            for ( int i = 0; i < Array.getLength( arrayN1 ); i++ )
            {
                Array.set( arrayN3, i, ArrayN.addArraysN( Array.get( arrayN1, i ), Array.get( arrayN2, i ), dimension-1, innerlength ) );
            }

            return arrayN3;
        }
    }
}

输出:

44444

44444
44444

Exception in thread "main" java.lang.IllegalArgumentException: array element type mismatch
    at java.lang.reflect.Array.set(Native Method)
    at ArrayN.addArraysN(ArrayN.java:85)
    at ArrayN.addArraysN(ArrayN.java:85)
    at ArrayN.main(ArrayN.java:41)

我发现了错误。它是以下行:

Object arrayN3 = Array.newInstance( Array.class, dimensions );

我不得不用整.class替换数组.class。更正后的行应为:

Object arrayN3 = Array.newInstance( int.class, dimensions );

现在我意识到代码的另一个问题:
由于innerlong参数,多维数组中的每个数组都必须具有相同的大小。如果数组更短,其他值将变为零:

44444

44444
44444

[[4, 4, 4, 4, 4], [4, 4, 4, 4, 4], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

所以我首先让matrix1matrix2长一点:

//Matrix
int[][] matrix1 = {{0, 1, 2, 3, 4}, {4, 3, 2, 1, 0}, {0, 1, 2, 3, 4}, {4, 3, 2, 1, 0}, {0, 1, 2, 3, 4}};
int[][] matrix2 = {{4, 3, 2, 1, 0}, {0, 1, 2, 3, 4}, {4, 3, 2, 1, 0}, {0, 1, 2, 3, 4}, {4, 3, 2, 1, 0}};

但这不是一个好的解决方案。< br> Nikoloz写了一个方法来找出数组的维数。使用它和另一个方法< code > arrayToString(Object)我现在编写的最终代码是:

import java.util.Arrays;
import java.lang.reflect.Array;
import java.util.List;
import java.util.ArrayList;

public class ArrayN
{
    public static void main( String[] args )
    {
        int[][] matrix1 = {{0, 1, 2, 3, 4}, {4, 3, 2, 1, 0}};
        int[][] matrix2 = {{4, 3, 2, 1, 0}, {0, 1, 2, 3, 4}};

        System.out.println( ArrayN.arrayToString( ArrayN.addArraysN( matrix1, matrix2 ) ) );

    }

    public static Object addArraysN( Object arrayN1, Object arrayN2 )
    {
        ArrayList<Integer> dimensions = new ArrayList<Integer>();
        ArrayN.getDimensions( arrayN1, dimensions );
        int[] dims = new int[dimensions.size()];
        for ( int i = 0; i < dims.length; i++ )
        {
            dims[i] = dimensions.get( i );
        }

        if ( dims.length == 0 )
        {
            return (int)arrayN1 + (int)arrayN2;
        }
        else
        {
            Object arrayN3 = Array.newInstance( int.class, dims );
            for ( int i = 0; i < Array.getLength( arrayN1 ); i++ )
            {
                Array.set( arrayN3, i, ArrayN.addArraysN( Array.get( arrayN1, i ), Array.get( arrayN2, i ) ) );
            }

            return arrayN3;
        }
    }

    public static void getDimensions( Object array, List<Integer> dimensions )
    {
        if ( array != null && array.getClass().isArray() )
        {
            dimensions.add( Array.getLength( array ) );
            if ( Array.getLength( array ) > 0)
            {
                ArrayN.getDimensions( Array.get( array, 0 ), dimensions );
            }
        }
    }

    public static String arrayToString( Object arr )
    {
        if ( arr instanceof byte[] )
            return Arrays.toString( (byte[])arr );
        else if ( arr instanceof short[] )
            return Arrays.toString( (short[])arr );
        else if ( arr instanceof int[] )
            return Arrays.toString( (int[])arr );
        else if ( arr instanceof long[] )
            return Arrays.toString( (long[])arr );
        else if ( arr instanceof float[] )
            return Arrays.toString( (float[])arr );
        else if ( arr instanceof double[] )
            return Arrays.toString( (double[])arr );
        else if ( arr instanceof char[] )
            return Arrays.toString( (char[])arr );
        else if ( arr instanceof boolean[] )
            return Arrays.toString( (boolean[])arr );
        else
            return Arrays.deepToString( (Object[])arr );
    }
}

另一种可能性是将维度1作为基本情况:

public static Object addArraysN( Object arrayN1, Object arrayN2 )
{
    ArrayList<Integer> dimensions = new ArrayList<Integer>();
    ArrayN.getDimensions( arrayN1, dimensions );
    int[] dims = new int[dimensions.size()];
    for ( int i = 0; i < dims.length; i++ )
    {
        dims[i] = dimensions.get( i );
    }
    if ( dims.length == 1 )
    {
        Object arrayN3 = Array.newInstance( int.class, dims );
        for ( int i = 0; i < Array.getLength( arrayN1 ); i++ )
        {
            int sum = ((int[])arrayN1)[i] + ((int[])arrayN2)[i];
            Array.set( arrayN3, i, sum );
        }
        return arrayN3;
    }
    else
    {
        Object arrayN3 = Array.newInstance( int.class, dims );
        for ( int i = 0; i < Array.getLength( arrayN1 ); i++ )
        {
            Array.set( arrayN3, i, (int[])ArrayN.addArraysN( Array.get( arrayN1, i ), Array.get( arrayN2, i ) ) );
        }

        return arrayN3;
    }
}

Java中如何对数组求和< br > Java中有没有可能动态构建一个多维数组?< br >通过反射迭代数组< br> Java反射-获取数组对象的大小< br >在运行时用Java创建n维数组< br >用Java初始化多维数组< br >查找二维数组的和Java
添加矩阵Java
Java矩阵数组

共有3个答案

贺懿轩
2023-03-14

这将真正做到你所要求的:

public static Object sumArbitraryDimensions(Object arrayOne, Object arrayTwo) {
    if (!arrayOne.getClass().equals(arrayTwo.getClass()) ||
            !arrayOne.getClass().isArray()) {
        throw new IllegalArgumentException("not an array");
    }

    int len = Array.getLength(arrayOne);
    if (len != Array.getLength(arrayTwo)) {
        throw new IllegalArgumentException("incomparable length");
    }

    Object sum;

    if (arrayOne instanceof Object[]) {
        sum = new Object[len];

        for (int i = 0; i < len; i++) {
            ((Object[])sum)[i] = sumArbitraryDimensions(
                    Array.get(arrayOne, i), Array.get(arrayTwo, i));
        }

    } else if (arrayOne instanceof byte[]) {
        sum = new byte[len];

        for (int i = 0; i < len; i++) {
            ((byte[])sum)[i] = (byte)(((byte[])arrayOne)[i] + ((byte[])arrayTwo)[i]);
        }

    } else if (arrayOne instanceof short[]) {
        sum = new short[len];

        for (int i = 0; i < len; i++) {
            ((short[])sum)[i] = (short)(((short[])arrayOne)[i] + ((short[])arrayTwo)[i]);
        }

    } else if (arrayOne instanceof int[]) {
        sum = new int[len];

        for (int i = 0; i < len; i++) {
            ((int[])sum)[i] = ((int[])arrayOne)[i] + ((int[])arrayTwo)[i];
        }

    } else if (arrayOne instanceof long[]) {
        sum = new long[len];

        for (int i = 0; i < len; i++) {
            ((long[])sum)[i] = ((long[])arrayOne)[i] + ((long[])arrayTwo)[i];
        }

    } else if (arrayOne instanceof float[]) {
        sum = new float[len];

        for (int i = 0; i < len; i++) {
            ((float[])sum)[i] = ((float[])arrayOne)[i] + ((float[])arrayTwo)[i];
        }

    } else if (arrayOne instanceof double[]) {
        sum = new double[len];

        for (int i = 0; i < len; i++) {
            ((double[])sum)[i] = ((double[])arrayOne)[i] + ((double[])arrayTwo)[i];
        }

    } else {
        throw new IllegalArgumentException("cannot sum, non-numerical");
    }

    return sum;
}

或者稍微不那么冗长但不那么简洁:

public static Object sumArbitraryDimensions(Object arrayOne, Object arrayTwo) {
    // exceptions unchecked

    int len = Array.getLength(arrayOne);

    if (arrayOne instanceof Object[]) {
        Object[] sum = new Object[len];

        for (int i = 0; i < len; i++) {
            ((Object[])sum)[i] = sumArbitraryDimensions(
                    Array.get(arrayOne, i), Array.get(arrayTwo, i));
        }

        return sum;

    } else {
        Double[] sum = new Double[len];

        // works for any numerical primitive type because
        // getDouble will perform a widening conversion
        for (int i = 0; i < len; i++) {
            sum[i] = Array.getDouble(arrayOne, i) + Array.getDouble(arrayTwo, i);
        }

        return sum;
    }
}

或者,如果您真的想达到可能的元素级别:

public static Object sumArbitraryDimensions(Object objectOne, Object objectTwo) {
    if (!arrayOne.getClass().equals(arrayTwo.getClass())) {
        throw new IllegalArgumentException("incomparable types");
    }

    // reflection cannot retrieve primitive types
    // here the returned arrays will be boxed

    if (objectOne.getClass().isArray()) {
        int len = Array.getLength(objectOne);

        if (len != Array.getLength(objectTwo)) {
            throw new IllegalArgumentException("incomparable lengths");
        }

        Object[] sum = new Object[len];

        for (int i = 0; i < len; i++) {
            sum[i] = sumArbitraryDimensions(
                    Array.get(arrayOne, i), Array.get(arrayTwo, i));
        }

        return sum;

    } else if (objectOne instanceof Byte) {
        return (byte)((Byte)objectOne + (Byte)objectTwo));

    } else if (objectOne instanceof Short) {
        return (short)((Short)objectOne + (Short)objectTwo));

    } else if (objectOne instanceof Integer) {
        return (Integer)objectOne + (Integer)objectTwo);

    } else if (objectOne instanceof Long) {
        return (Long)objectOne + (Long)objectTwo);

    } else if (objectOne instanceof Float) {
        return (Float)objectOne + (Float)objectTwo);

    } else if (objectOne instanceof Double) {
        return (Double)objectOne + (Double)objectTwo);

    } else {
        throw new IllegalArgumentException("cannot sum, non-numerical");
    }
}

与常规处理相比,所有这些都将非常慢,因为所有的检查。我个人建议不要以任何形式或形状这样做。我看不出它有什么用。只需编写高达N维的重载方法:

public static int[] sumArrays(int[] arrayOne, int[] arrayTwo) {
    assert arrayOne != null && arrayTwo != null && arrayOne.length == arrayTwo.length;

    int[] sum = new int[Math.min(arrayOne.length, arrayTwo.length)];

    for (int i = 0; i < sum.length; i++) {
        sum[i] = arrayOne[i] + arrayTwo[i];
    }
    return sum;
}

public static int[][] sumArrays(int[][] arrayOne, int[][] arrayTwo) {
    assert arrayOne != null && arrayTwo != null && arrayOne.length == arrayTwo.length;

    int[][] sum = new int[Math.min(arrayOne.length, arrayTwo.length)][];

    for (int i = 0, k; i < sum.length; i++) {
        assert arrayOne[i] != null && arrayTwo[i] != null && arrayOne[i].length == arrayTwo[i].length;

        sum[i] = new int[Math.min(arrayOne[i].length, arrayTwo[i].length)];

        for (k = 0; k < sum[i].length; k++) {
            sum[i][k] = arrayOne[i][k] + arrayTwo[i][k];
        }
    }
    return sum;
}

public static int[][][] sumArrays(int[][][] arrayOne, int[][][] arrayTwo) {
    assert arrayOne != null && arrayTwo != null && arrayOne.length == arrayTwo.length;

    int[][][] sum = new int[Math.min(arrayOne.length, arrayTwo.length)][][];

    for (int i = 0, k, h; i < sum.length; i++) {
        assert arrayOne[i] != null && arrayTwo[i] != null && arrayOne[i].length == arrayTwo[i].length;

        sum[i] = new int[Math.min(arrayOne[i].length, arrayTwo[i].length)][];

        for (k = 0; k < sum[i].length; k++) {
            assert arrayOne[i][k] != null && arrayTwo[i][k] != null && arrayOne[i][k].length == arrayTwo[i][k].length;

            sum[i][k] = new int[Math.min(arrayOne[i][k].length, arrayTwo[i][k].length)];

            for (h = 0; h < sum[i][k].length; h++) {
                sum[i][k][h] = arrayOne[i][k][h] + arrayTwo[i][k][h];
            }
        }
    }
    return sum;
}
贺善
2023-03-14

问题是您不能像现在这样处理数组:您在< code>addVectorsN(...)那实际上是< code >(Object)matric 1 ,所以< code>int[][]。但是,你像< code>(int)vectorN1一样访问它,这是错误的,因为它实际上是一个数组,而不是一个int。因此,应该像这样访问vector n1:< code > int I =...;向量n1[I];然后我会将vectorN1保持为< code>int[][],而不是将其转换为< code>Object。我也会为vectorN2做同样的事情。

编辑:

我会改变

添加向量N( (对象)矩阵1, (对象)矩阵2, 2, 5 )要成为

addVectorsN(matrice1, matrice2,2,5))

你可以像< code>(int)vectorN1一样访问它

public static Object addVectorsN( Object vectorN1, Object vectorN2, 
    int dimension, int innerlength )
{
    if ( dimension == 0 )
    {
        return (int)vectorN1 + (int)vectorN2; (...) 

我会改为:

public static Object addVectorsN(int[][] vectorN1, int[][] vectorN2, 
    int dimension, int innerlength )

编辑2:

也许你需要这样的东西:

    if (vectorN1.length == 1 && vectorN2.length == 1)
    {
        if (vectorN1[0].length == 1  && vectorN2[0].length == 1)
        {
            return vectorN1[0][0] + vectorN2[0][0];
        }
    }
上官扬
2023-03-14

这里是完整而简单的解决方案。可以将任何维度数组传递给< code>copyArray方法。

package com.azry.test;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

public class MultiDimArray {

    public Object copyArray(Object srcArray1, Object srcArray2) {

        ArrayList<Integer> dimensions = new ArrayList<Integer>();
        getDimensions(srcArray1, dimensions);
        int[] dims = new int[dimensions.size()];
        for (int i = 0; i < dims.length; i++) {
            dims[i] = dimensions.get(i);
        }

        Object dstArray = Array.newInstance(int.class, dims);
        copyArray(srcArray1, srcArray2, dstArray);
        return dstArray;
    }

    public void copyArray(Object srcArray1, Object srcArray2, Object dstArray) {
        if (srcArray1 != null && srcArray1.getClass().isArray()) {
            if (srcArray1 instanceof int[]) {
                int[] s1 = (int[])srcArray1;
                int[] s2 = (int[])srcArray2;
                int[] d = (int[])dstArray;
                for (int i = 0; i < s1.length; i++) {
                    d[i] = s1[i] + s2[i];
                }
            }
            for (int i = 0; i < Array.getLength(srcArray1); i++) {
                copyArray(Array.get(srcArray1, i), Array.get(srcArray2, i), Array.get(dstArray, i));
            }
        }
    }

    public void getDimensions(Object array, List<Integer> dimensions) {
        if (array != null && array.getClass().isArray()) {
            dimensions.add(Array.getLength(array));
            if (Array.getLength(array) > 0) {
                getDimensions(Array.get(array, 0), dimensions);
            }
        }
    }

    public static void main(String[] args) {

        int[][][] srcArray1 = new int[2][3][4];
        for (int i = 0; i < srcArray1.length; i++) {
            for (int j = 0; j < srcArray1[i].length; j++) {
                for (int k = 0; k < srcArray1[i][j].length; k++) {
                    srcArray1[i][j][k] = 2;
                }
            }
        }

        int[][][] srcArray2 = new int[2][3][4];
        for (int i = 0; i < srcArray2.length; i++) {
            for (int j = 0; j < srcArray2[i].length; j++) {
                for (int k = 0; k < srcArray2[i][j].length; k++) {
                    srcArray2[i][j][k] = 3;
                }
            }
        }

        int[][][] dstArray = (int[][][])new MultiDimArray().copyArray(srcArray1, srcArray2);

        for (int i = 0; i < dstArray.length; i++) {
            for (int j = 0; j < dstArray[i].length; j++) {
                for (int k = 0; k < dstArray[i][j].length; k++) {
                    System.out.println("[" + i + "," + j + "," + k + "] = " + dstArray[i][j][k]);
                }
            }
        }
    }
}
 类似资料:
  • 我正在使用Javascript(ES6)/FacebookReact,并尝试获得大小不同的数组的前3个元素。我想做与Linq take(n)等价的操作。 在我的Jsx文件中,我有以下内容: 然后我尝试了前3个项目 这不起作用,因为地图没有一个设置的函数。 你能帮忙吗?

  • 问题内容: 我需要有一个n维字段,其中n基于构造函数的输入。但是我什至不确定这是否可行。是吗? 问题答案: 快速的解决方案:你可以用非通用近似它的的…要深,因为你需要。但是,使用快速可能会很尴尬。 另一种需要更多工作的选择可能是使用基础平面数组表示形式来实现您自己的类型,在其中您内部计算索引,并为访问器方法提供vararg参数。我不确定它是否完全可行,但可能值得一试… 粗略的示例(未经测试,没有溢

  • 问题内容: 我已经做了很多关于溢出和谷歌的环顾工作,但是对于我的具体情况,结果都不起作用。 我有一个名为$ holder的占位符数组,值如下: 我正在尝试从此多维数组中提取不同/唯一的值。我想要的最终结果是一个包含(13,121)的变量,或者是(最好是)一个如下数组:Array([0] => 13 [1] => 121) 再次,我尝试了序列化等,但是当在每个数组中使用单个键进行操作时,我不太了解它

  • 问题内容: 假设我有个数组,另一个数组。我如何得到结果数组? 问题答案: 如果您不需要保留订单,并考虑和保持一致:

  • 本文向大家介绍如何在MongoDB中汇总总和以获得总数?,包括了如何在MongoDB中汇总总和以获得总数?的使用技巧和注意事项,需要的朋友参考一下 要在MongoDB中汇总总和以获取总计数,可以使用$sum运算符。要了解上述概念,让我们使用文档创建一个集合- 在method的帮助下显示集合中的所有文档。查询如下- 以下是输出- 这是获取总数的查询。 情况1-查询如下- 以下是输出- 这是在Mong

  • 我想做一个模板,在那里我可以输入一个索引,它会给我在那个索引的类型。我知道我可以用来实现,但我想自己实现它。例如,我想这样做, ...它会给出位置的类型(因为数组是从0开始索引的)。我怎么能这么做?多谢了。