【发布时间】:2013-11-29 23:57:43
【问题描述】:
在 Java 中添加两个 n 维数组
添加向量
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
应该有一种方法可以使用递归添加两个未知维度的数组。
例如下面的代码使用了假设函数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]]]
现在我想知道如何实现这个功能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
}
}
可以使用java.lang.reflect.Array 中的newInstance 方法创建新数组。
循环可以像这样实现:
for ( int i = 0; i < ((int[])arr1).length; i++ )
sum = addArraysN( ((int[])arr1)[i], ((int[])arr2)[i] );
问题
但我偶然发现了很多运行时错误和其他问题。有没有人知道如何实现这个addArrayN-method?
也应该可以使用ArrayList 或任何其他类,但我主要对如何使用数组执行此操作感兴趣...(尽管如此,如果有人知道,请发布!)
提前致谢
附录 1
我的原始代码:
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)
附录 2
我发现了错误。它是以下行:
Object arrayN3 = Array.newInstance( Array.class, dimensions );
我不得不将Array.class 替换为int.class。更正后的行应该是:
Object arrayN3 = Array.newInstance( int.class, dimensions );
现在我意识到代码存在的另一个问题:
由于 innerlength 参数,多维数组中的每个数组都必须具有相同的大小。如果数组更短,则其他值为零:
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]]
所以我先把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}};
但这不是一个好的解决方案。
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 );
}
}
另一种可能性是将维度 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;
}
}
相关问题
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
【问题讨论】:
-
只是一个想法:将原始数组包装在一个接受 N 个索引值并将其转换为单个索引以从原始数组中读取的类中要容易得多。它强制执行非参差不齐,允许您通过更改尺寸来重塑形状,并允许您在不复制内容的情况下交换列的顺序。至于您在问题中提到的最后一点:不。你不会得到适用于 List 和数组的东西。它们在 java 中几乎没有关系。
-
我很困惑,为什么矩阵加法需要反射?您只能将 mxn 矩阵相加,知道一个矩阵的维数意味着您知道和的维数。
-
But I stumbled over a lot of runtime errors and other problems.究竟是哪些?
标签: java arrays reflection recursion multidimensional-array