如何在Java中获得两个n维数组的总和?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20020599/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the sum of two n-dimensional arrays in Java?
提问by John
Adding two n-dimensional arrays in Java
在 Java 中添加两个 n 维数组
addVectors
添加向量
Two 1-dimensional arrays / vectors in Java can be added like this:
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;
}
addMatrices
添加矩阵
Two 2-dimensional arrays / matrices in Java can be added like this:
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;
}
Both functions require the arrays to be of the same size to avoid an arrayOutOfBoundsException.
这两个函数都要求数组大小相同,以避免出现arrayOutOfBoundsException.
addArraysN
添加数组N
There should be a way to add two arrays of unknown dimension using recursion.
For example, the following code using the hypothetical function addArraysN( arr1, arr2 )
应该有一种方法可以使用递归添加两个未知维度的数组。
例如下面的代码使用了假设函数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 ) );
should output
应该输出
[[[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]]]
Now I'm wondering about how to implement this function addArraysN( arr1, arr2 ).
I started out with the following pseudo code:
现在我想知道如何实现这个功能addArraysN( 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
}
}
New arrays can be created using the newInstance-method from java.lang.reflect.Array.
Looping can be made possible like this:
可以使用java.lang.reflect.Array 中的newInstance-method创建新数组。
循环可以这样实现:
for ( int i = 0; i < ((int[])arr1).length; i++ )
sum = addArraysN( ((int[])arr1)[i], ((int[])arr2)[i] );
Question
题
But I stumbled over a lot of runtime errors and other problems. Has anybody an idea or even a solution on how to implement this addArrayN-method?
但是我偶然发现了很多运行时错误和其他问题。有没有人有关于如何实现这种addArrayN方法的想法甚至解决方案?
It should be also possible to work with ArrayListor any other Class but I'm mainly interested on how to do this with arrays... (Nevertheless if someone knows it please post!)
也应该可以与ArrayList或任何其他类一起工作,但我主要对如何使用数组执行此操作感兴趣......(尽管如此,如果有人知道,请发布!)
Thanks in advance
提前致谢
appendix 1
附录1
My original code:
我的原始代码:
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;
}
}
}
Output:
输出:
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)
appendix 2
附录 2
I've found the error. It was the following line:
我发现了错误。这是以下行:
Object arrayN3 = Array.newInstance( Array.class, dimensions );
I had to replace Array.classwith int.class. The corrected line should be:
我不得不替换Array.class为int.class. 更正后的行应该是:
Object arrayN3 = Array.newInstance( int.class, dimensions );
Now I realized another problem the code has:
Every array in the multidimensional array has to be of the same size because of the innerlength argument. If arrays are shorter the other values become zero:
现在我意识到代码存在的另一个问题:
由于内部长度参数,多维数组中的每个数组都必须具有相同的大小。如果数组较短,则其他值为零:
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]]
So I first made matrix1and matrix2a bit longer:
所以,我首次提出matrix1和matrix2多一点的时间:
//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}};
But that's not a good solution.
Nikoloz wrote a method to find out the dimensions of arrays. Using it and another method arrayToString( Object )I wrote my final code is now:
但这不是一个好的解决方案。
Nikoloz 写了一个方法来找出数组的维数。使用它和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 );
}
}
Another possibility would be to take dimension 1 as the base case:
另一种可能性是将维度 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;
}
}
Related questions
相关问题
How to sum arrays in Java
Is it possible to dynamically build a multi-dimensional array in Java?
Iterating over arrays by reflection
Java Reflection - Get size of array object
Creating an n-dimension Array in Java during runtime
Initialising a multidimensional array in Java
finding sum of two dimensional array java
Adding matrices Java
Java Matrices Arrays
如何在 Java 中对数组求和
是否可以在 Java中动态构建多维数组?
通过反射迭代数组
Java 反射 - 获取数组对象的大小
在运行时在 Java 中创建 n 维数组 在 Java 中
初始化多维数组
查找二维数组的总和 java
添加矩阵 Java
Java 矩阵数组
采纳答案by Nikoloz
Here is complete and simple solution. You can pass any dimension arrays to copyArraymethod.
这是完整而简单的解决方案。您可以将任何维度数组传递给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]);
}
}
}
}
}
回答by Lucia Pasarin
The problem is that you cannot treat arrays like you are currently doing: You receive Object vectorN1in addVectorsN(...)that is actually (Object)matrice1, so int[][]. But then, you access it like (int)vectorN1, which is wrong, because it's actually an array, not an int. So, you should access to vectorN1 like this: int i = ...; vectorN1[i];and I would then keep vectorN1 as int[][]instead of converting it into an Object. And I would do the same for vectorN2 as well.
问题是您不能像当前那样对待数组:您实际上收到Object vectorN1的addVectorsN(...)是(Object)matrice1,所以int[][]. 但是,你像 那样访问它(int)vectorN1,这是错误的,因为它实际上是一个数组,而不是一个整数。因此,您应该像这样访问 vectorN1:int i = ...; vectorN1[i];然后我将 vectorN1 保持为 asint[][]而不是将其转换为Object. 我也会对 vectorN2 做同样的事情。
EDIT:
编辑:
I would change
我会改变
addVectorsN( (Object)matrice1, (Object)matrice2, 2, 5 ) )to be
addVectorsN( (Object)matrice1, (Object)matrice2, 2, 5 ) )成为
addVectorsN( matrice1, matrice2, 2, 5 ) )
addVectorsN( matrice1, matrice2, 2, 5 ) )
and you are accessing it like (int)vectorN1in
并且您正在访问它像(int)vectorN1在
public static Object addVectorsN( Object vectorN1, Object vectorN2,
int dimension, int innerlength )
{
if ( dimension == 0 )
{
return (int)vectorN1 + (int)vectorN2; (...)
which I would change to be:
我会改为:
public static Object addVectorsN(int[][] vectorN1, int[][] vectorN2,
int dimension, int innerlength )
EDIT2:
编辑2:
and maybe you need something like this:
也许你需要这样的东西:
if (vectorN1.length == 1 && vectorN2.length == 1)
{
if (vectorN1[0].length == 1 && vectorN2[0].length == 1)
{
return vectorN1[0][0] + vectorN2[0][0];
}
}
回答by Radiodef
This will literally do what you are asking:
这将按字面意思执行您的要求:
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;
}
Or the slightly less verbose but less concise:
或者稍微不那么冗长但不那么简洁的:
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;
}
}
Or if you really want to get down to the element level that is possible:
或者,如果您真的想深入到可能的元素级别:
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");
}
}
All of these are going to be very slow compared to regular processing because of the all the examination. I would personally recommend against doing this in any way shape or form. I don't see the use in it. Just write overloaded methods up to N dimensions:
由于所有的检查,与常规处理相比,所有这些都将非常缓慢。我个人建议不要以任何形式或形式这样做。我看不出它的用途。只需编写最多 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;
}

