矩阵乘法-对输入格式的研究

来源:互联网 发布:激光脉冲价格知乎 编辑:程序博客网 时间:2024/06/05 05:34

       最近学习java,写到一道关于矩阵乘法的题目。关于矩阵乘法的代码实现并不困难,但是输入的格式上遇到点小麻烦。

下面给出题目要求:


       第一次尝试:通过控制台输入要输入的矩阵的行数m与列数n,定义一个二维数组: double[m][n] ,然后将输入的数据放进数组里面。

       第二次尝试:上面的方法不能满足注意事项中的第一点,因为程序默认会得到一个矩阵。这次想要将矩阵在一行中表示出来,矩阵的各行以 “,”作为分隔,矩阵输完以“;”为标识,并在末尾添加输入的矩阵的行数。输入格式如下:

                          1 2 3,4 5 6,7 8 9;3

        这个格式提供了矩阵的行数信息,结合输入的数据个数,可以判断输入的数据能否构成一个矩阵。(实现在源代码1中,但是还有点问题)

下面给出源代码1:

package bookExample;//视自己的情况而定import java.io.IOException;import java.io.*;import java.util.ArrayList;import java.util.Scanner;import java.util.StringTokenizer;public class MatrixMultiplication {private static BufferedReader buf;private static  Scanner scanner;public static void main(String[] args) throws IOException{        System.out.println("inout a matrix and the number of matrix's col(following an example):");        System.out.println("1 2 3,4 5 6,7 8 9;3\n");//1.1 1.1 1.1,1.1 1.1 1.1,1.1 1.1 1.1;3        System.out.println("input two matrixs as the eample:");        int n;        while(true)         {        matrixShow( matrixMultiplier( matrixIn() , matrixIn() ) );            System.out.println("input n\n(if n =0 then quit else continue):");        n = scanner.nextInt();        if( n == 0 ) break;          }System.out.println("Quit!");                //下面的两个矩阵为第一次尝试的时候实验用的;double[][] m1= {{1,1,1},{1,1,1},{1,1,1},};double[][] m2= {{1,1,1},{1,1,1},{1,1,1},};//double[][] m = matrixMultiplier(m1,m2);//matrixShow(matrixMultiplier(m1,m2));//matrixShow(matrixIn())}public static double[][] matrixMultiplier(double m1[][],double m2[][])//矩阵相乘{int numofcolm1,numofcolm2;numofcolm1 = m1[0].length;numofcolm2 = m2[0].length;if( m2.length != numofcolm1 ){   System.out.println("m1's colnum != m2's rawnum");return new double[0][0];}for(int i=1; i<m1.length; i++){double line[] = m1[i];if( line.length != numofcolm1 ){   System.out.println("m1 isn't a matrix!");return new double[0][0]; }}for(int i=1; i<m2.length; i++){double line[] = m2[i];if( line.length != numofcolm2 ){System.out.println("m2 isn't a matrix!");return new double[0][0]; }}double[][] m =new double[numofcolm1][numofcolm2];double sum = 0;for(int i = 0; i<m1.length; i++){for(int j = 0; j<numofcolm2; j++){for(int k = 0; k<m2.length; k++)          sum += m1[i][k]*m2[k][j];m[i][j]=sum;sum = 0;}}return m;}public static void matrixShow(double m[][])//二维矩阵显示{if( m.length != 0 ){int numofcolm = m[0].length; for(int i = 0; i<m.length; i++)for(int j = 0; j<numofcolm; j++){System.out.printf("%.3f\t",m[i][j]);//小数位数控制保对齐if( j==numofcolm-1 ) System.out.println();}}else System.out.println("inputERR\nshutdown");}public static double[][] matrixIn() throws IOException//矩阵输入{    scanner = new Scanner(System.in);ArrayList<Double>  alist = new ArrayList<Double>();buf = new BufferedReader(new InputStreamReader(System.in));String str1 = buf.readLine();StringTokenizer str11 = new StringTokenizer(str1," ,;");int n = 0; while( str11.hasMoreTokens() ){  alist.add( Double.parseDouble( str11.nextToken() ) );n++;}        double numofRaw = alist.get(n-1);        double totalNum = alist.size()-1;        int numofCol = (int) ( totalNum/numofRaw );// + numofRaw - totalNum%numofRaw,如何直接确定列数        double[][] aaa = new double[ (int) numofRaw ][ numofCol ];for(int i = 0; i<totalNum;i++ ){aaa[(int) (i/numofRaw)][i%numofCol]=alist.get(i);}return  aaa;}}

程序运行效果如下图:

   

第三次尝试:这次想要实现不输入矩阵的行数和列数,等用户输完全部的数据后在进行操作。输入格式如下:

                        1 2 3
                        4 5 6
                        7 8 9
                        end

                        这样的输入看起来比较舒服。

下面主要说明第三次尝试使用的办法。

        使用了动态数组( ArrayList<String>  alist = new ArrayList<String>() ),能够实现动态地增加或减少元素,在这里主要说增加( 使用alist.add() 来添加元素),这样就能够很好地解决行数未知的矩阵的输入问题;将每一行的输入作为动态数组的元素,类型为字符串,以 “end”为结束标志,这样我们输入的信息就以字符串数组的形式存储起来了,而矩阵行数通过  alist.size()   就可以求出。

        下一步据通过 split(" "),将输入过程中添加进去的空格作为两个元的分隔,可以将一行数据分割成若干个元素,类型依然为字符串型,放进一个字符串数组里面,每一行都可以分割成具有若干元素的字符串数组。如果每一个字符串数组的元素个数都相等,可以知道输入的数据能够构成一个矩阵,否则输出错误提示I信息。

         若输入的数据能够构成一个矩阵,则通过前面两步能够确定矩阵的行数和列数,接着将前面分隔好的字符串数组的元素强制转化成double类型,放进数组里面,得到最终的结果。

下面给出源代码2:

package test;//根据自己的情况而定import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayList;import java.util.Scanner;public class MatrixMultiplication {private static BufferedReader buf;private static  Scanner scanner = new Scanner(System.in);static int orderMatrix = 0 ;public static void main(String[] args) throws IOException {System.out.println("the format of matrix (following an example):");System.out.println("1 2 3\n4 5 6\n7 8 9\nend");//1.1 1.1 1.1,1.1 1.1 1.1,1.1 1.1 1.1;3    System.out.println("input two matrixs as the eample:");        int n;        while(true)         {          double[][] m1 = matrixIn();        while( matrixJudge( m1 ) )               m1 = matrixIn();        double[][] m2 = matrixIn();                           while( matrixJudge( m2 ) )              m2 = matrixIn();          double[][] m3 = matrixMultiplier( m1 , m2 );                if( !(m3.length == 0) )                matrixShow( m3 );            System.out.println("input n\n(if n =0 then quit else continue):");        n = scanner.nextInt();        if( n == 0 ) break;          }System.out.println("Quit!");   }static boolean matrixJudge(double[][] m)//矩阵正误检查{if( ( (m.length) == 0) ){System.out.println("this Input isn't a matrix!Please Retry:");return true;}elsereturn false;}static double[][] matrixMultiplier(double m1[][],double m2[][])//矩阵相乘{int numofRawm1,numofColm1,numofRawm2,numofColm2;if( (m1[0].length != m2.length) ){System.out.println("m1's colnum != m2's rawnum");orderMatrix = 0;return new double[0][0];}numofRawm2 = m2.length;numofColm1 = m1[0].length;numofRawm1 = m1.length;numofColm2 = m2[0].length;double[][] m =new double[numofRawm1][numofColm2];double sum = 0;for(int i = 0; i<numofRawm1; i++){for(int j = 0; j<numofColm2; j++){for(int k = 0; k<numofRawm2; k++)          sum += m1[i][k]*m2[k][j];m[i][j] = sum;sum = 0;}}System.out.println("Result:");return m;}    static void matrixShow(double m[][])//矩阵显示{int flag = m.equals(new double[0][0])?0:1;        switch(flag)    {    case 0 : System.out.println("inputERR,shutdown");break;                          case 1 :         orderMatrix = 0;     for(int i = 0; i<m.length; i++)     for(int j = 0; j<m[0].length; j++)     {     System.out.printf("%.3f\t",m[i][j]);//小数位数控制保对齐     if( j==m[0].length-1 )      System.out.println();     }}}    static double[][] matrixIn() throws IOException//矩阵输入{      ArrayList<String>  alist = new ArrayList<String>();buf = new BufferedReader(new InputStreamReader(System.in));switch(orderMatrix){case 0 : System.out.println("input first matrix :"); break;case 1 : System.out.println("input second matrix :"); break;}String str1 = buf.readLine();int colLen = 0;while(true){if( str1.endsWith("end") ) {break;}alist.add(str1);str1 = buf.readLine();}    String[] arr= alist.get(0).split(" ");//正则表达式?    colLen = arr.length;    //System.out.println(alist.size());//测试用    boolean flag = false;    for ( int i = 0; i<alist.size(); i++)//检测输入能否构成一个矩阵    {    arr= alist.get(i).split(" ");    if( arr.length!= colLen)     {       System.out.println("InputErr!-");    System.out.println("Error happened at line:"+(i+1)+"\t errorMsg:"+alist.get(i));        return new double[0][0];    }    flag = true;    }        if(flag)    {        orderMatrix = (orderMatrix+1)%2;    int colNum = arr.length;    int rawNum = alist.size();    double[][] m = new double [ rawNum ][ colNum ];    for(int i = 0; i < rawNum; i++)    {    arr= alist.get(i).split(" ");        for(int j = 0; j<colNum; j++)    {      m[i][j] = Double.parseDouble(arr[j]);    }        }    return m;    }    else     return new double[0][0];}}

程序运行效果如下图:


新人第一次。终于结束。