草庐IT

java - Java中如何获取两个n维数组的和?

coder 2024-03-20 原文

在Java中添加两个n维数组

添加 vector

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

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

添加数组N

应该有一种方法可以使用递归将两个未知维度的数组相加。
例如,以下代码使用假设函数 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.ArraynewInstance 方法创建新数组.
循环可以像这样成为可能:

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

问题

但是我偶然发现了很多运行时错误和其他问题。关于如何实现此 addArrayN 方法,有人有想法甚至解决方案吗?

应该也可以使用 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 );

我必须用 int.class 替换 Array.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]]

所以我首先让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}};

但这不是一个好的解决方案。
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

最佳答案

这是完整而简单的解决方案。您可以将任何维度数组传递给 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]);
                }
            }
        }
    }
}

关于java - Java中如何获取两个n维数组的和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20020599/

有关java - Java中如何获取两个n维数组的和?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  8. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  9. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  10. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

随机推荐