如何在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 ArrayList
or 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.class
with 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 matrix1
and matrix2
a 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 copyArray
method.
这是完整而简单的解决方案。您可以将任何维度数组传递给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 vectorN1
in 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)vectorN1
in
并且您正在访问它像(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;
}