简体   繁体   English

从文件 Java 中获取矩阵

[英]Get matrix from a file Java

I currently have a text file in the format我目前有一个格式的文本文件

matrix
row
a
b
c
row
d
e
f
row
g
h
i
row
j
k
l
matrix
row
m
n
o
p
q
row
r
s
t
u
v

I would like to convert this into two integer matrices (stored as 2 2D arrays), in the format我想将其转换为两个整数矩阵(存储为 2 个二维数组),格式为

a b c

d e f

g h i

j k l

and

m n o p q

r s t u v

So far, I have created a Scanner object of the file and put each line in a text array:到目前为止,我已经创建了文件的 Scanner 对象并将每一行放入一个文本数组中:

Scanner sf = new Scanner(new File("C:\\textfiles\\matrices.txt"));
int maxIndex = -1;
String text[] = new String[10000]; // I added more than necessary for safety
while (sf.hasNext()){
    maxIndex++;
    text[maxIndex] = sf.nextLine();
}
sf.close();

This way, the text file is now contained in a string array, where each line is a new element of the array.这样,文本文件现在包含在一个字符串数组中,其中每一行都是数组的一个新元素。 Right now, I would like to partition the array into two arrays with each array being the matrices.现在,我想将数组分成两个数组,每个数组都是矩阵。 How should I continue?我该如何继续? (note: I am a total beginner and desire answers that are simple (no arraylist, hashmap, etc., and that's why this question is not a duplicate of How to read two matrices from a txt file in java because it uses BufferedReader, and there are other potential duplicate questions, so I would like to clear this up) (注意:我是一个完全的初学者,希望得到简单的答案(没有数组列表、哈希图等,这就是为什么这个问题不是How to read two matrices from a txt file in java因为它使用 BufferedReader,以及还有其他潜在的重复问题,所以我想澄清一下)

What I currently have after the top:我目前在顶部之后拥有的:

int counter = 0;
int iCounter = 0; // row
int jCounter = 0; // column

int matrix1[][];
int matrix2[][];
while (counter < maxIndex){
    if (counter = 0)
    {
        \\not yet written...
    }
    \\not yet written...
}

This does what you want.这做你想要的。 Unfortunately doing this with 2D arrays is considerably harder since once you set the size of an array its difficult to manage changing it.不幸的是,使用 2D 数组执行此操作要困难得多,因为一旦您设置了数组的大小,就很难对其进行更改。 Therefore using ArrayList is much easier.因此使用ArrayList容易得多

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

class Main {

    public static final String MATRIX = "matrix";
    public static final String ROW = "row";

    public static void main(String[] args) throws FileNotFoundException {
        // Use correct file name here
        Scanner sf = new Scanner(new File("matrices.txt"));

        // This is a List of 2D Lists
        List<List<List<String>>> matrices = new ArrayList<>();

        // easier to process lines as we're reading them in so we
        // only iterate over the file once
        while (sf.hasNext()) {
            boolean hasBeenProcessed = false;

            String inputValue = sf.nextLine();

            switch (inputValue) {
                case MATRIX:
                    ArrayList<List<String>> matrix = new ArrayList<>();
                    matrices.add(matrix);
                    hasBeenProcessed = true;
                    break;
                case ROW:
                    List<List<String>> currentMatrix = getMatrixBeingProcessed(matrices);
                    currentMatrix.add(new ArrayList<String>());
                    hasBeenProcessed = true;
                    break;
            }
            if (!hasBeenProcessed) {
                List<List<String>> currentMatrix = getMatrixBeingProcessed(matrices);
                List<String> currentRow = getCurrentRow(currentMatrix);
                currentRow.add(inputValue);
            }
        }

        // Print out the results:
        int i = 1;
        for (List<List<String>> matrix : matrices) {
            System.out.println("Matrix " + i);
            for (List<String> row : matrix) {
                for (String element : row) {
                    System.out.print(element + " "); // no newline until end of the row
                }
                System.out.println(); // new line
            }
            i++;
            System.out.println(); // new line
        }
    }

    private static List<String> getCurrentRow(List<List<String>> currentMatrix) {
        int lastRow = currentMatrix.size() - 1;
        return currentMatrix.get(lastRow);
    }

    private static List<List<String>> getMatrixBeingProcessed(List<List<List<String>>> matrices) {
        int lastMatrix = matrices.size() - 1;
        List<List<String>> currentMatrix = matrices.get(lastMatrix);
        return currentMatrix;
    }
}

Output:输出:

Matrix 1
a b c 
d e f 
g h i 
j k l 

Matrix 2
m n o p q 
r s t u v 


Process finished with exit code 0

As @Rob said, it's really cumbersome to do this without dynamic data structures such as ArrayList's.正如@Rob 所说,如果没有 ArrayList 等动态数据结构,这样做真的很麻烦。 But nevertheless, here's a code that does your job (considering you have only two matrices), without using any List's:但是,这里有一个代码可以完成您的工作(考虑到您只有两个矩阵),而不使用任何列表:

int counter = 0;
int iCounter = 0; // row
int jCounter = 0; // column
int matrix1[][];
int matrix2[][];

int rowSize = 0, numberOfRows = 0;
counter = 2;
while (!text[counter].equals("row") && !text[counter].equals("matrix")) {
  counter++;
  rowSize++;
}

//now we have the row size
numberOfRows = 1;
while (!text[counter].equals("matrix")) {
  if (text[counter].equals("row"))
    numberOfRows++;
  counter++;
}
//now we have the total number of rows
matrix1 = new int[numberOfRows][rowSize];

counter = 2;  //to start from the first matrix
//now counter should point to the first row of the first matrix
while (!text[counter].equals("matrix")) {
  jCounter = 0;
  while (!text[counter].equals("row")
         && !text[counter].equals("matrix")) {
    matrix1[iCounter][jCounter++] = Integer.parseInt(text[counter]);
    //supposing your input is Integers, otherwise, you can change
    //it to the corresponding type (i.e. Long, Double, etc)
    counter++;
  }
  iCounter++;
  if (!text[counter].equals("matrix"))
    counter++;
}
//now we finished with the first matrix, and the counter points to
//the first "row" of the second matrix, so we do the same thing again
rowSize = 0;
numberOfRows = 0;
int startOfSecondMatrix = counter + 2;  //save this for later
counter += 2;  // so that counter points to the first number
while (counter < text.length && !text[counter].equals("row")) {
  counter++;
  rowSize++;
}
numberOfRows = 1;
while (counter < text.length) {
  if (text[counter].equals("row"))
    numberOfRows++;
  counter++;
}
matrix2 = new int[numberOfRows][rowSize];

counter = startOfSecondMatrix;
iCounter = 0;
while (counter < text.length) {
  jCounter = 0;
  while (counter < text.length && !text[counter].equals("row")) {
    matrix2[iCounter][jCounter++] = Integer.parseInt(text[counter]);
    counter++;
  }
  iCounter++;
  counter++;
}

For each matrix we perform the same operations: -We first go through the matrix to count its size to be able to initialize it, after that, we go row by row, and parse each number.对于每个矩阵,我们执行相同的操作: - 我们首先遍历矩阵以计算其大小以便能够对其进行初始化,然后逐行分析每个数字。
You might as well put all the work for one matrix into a function (and take care of the bounds) and call it as long you still have more matrices.您不妨将一个矩阵的所有工作都放在一个函数中(并处理边界)并在您还有更多矩阵时调用它。

Since you don't want to use List and arrays can't be resized once initialized, this is not easy.由于您不想使用 List 并且数组一旦初始化就无法调整大小,因此这并不容易。

There are two ways: Read the file and initialize arrays knowing the size (as @Maaddy posted) or 'resizing' arrays.有两种方法:读取文件并初始化知道大小的数组(如@Maaddy 发布的)或“调整大小”数组。 That's not possible but it is if you use Arrays.copyOf() so you can create a new array.这是不可能的,但如果您使用Arrays.copyOf()可以创建一个新数组。

The idea is create a 'tridimensional' array where you can store: matrix, row and column;这个想法是创建一个“三维”数组,您可以在其中存储:矩阵、行和列; and then start to read the file.然后开始读取文件。 Every time you find a word the entire array will be updated creating a new array with one length more.每次找到一个单词时,整个数组都会更新,创建一个长度增加一个的新数组。

If the word is 'matrix' the extra length will be added to the first position (the position who 'store' the matrix)如果单词是“矩阵”,则额外的长度将被添加到第一个位置(“存储”矩阵的位置)

If the word is 'row' then the space will be added for the current matrix.如果单词是“row”,则将为当前矩阵添加空格。 So in this way, the current matrix will have one more array where store the column values.因此,通过这种方式,当前矩阵将多一个存储列值的数组。

If the word is other then is a value for the column.如果单词是 other,则是该列的值。 The column is resized and added to the correct position.该列被调整大小并添加到正确的位置。

Note that if a word 'matrix' or 'row' is found, the new array is initialized with no length.请注意,如果找到单词 'matrix' 或 'row',则新数组将初始化为没有长度。 This is because will be resized later, when is necessary.这是因为稍后会在必要时调整大小。

The code is as follows:代码如下:

//Initialize array with no positions
String[][][] arrays = new String[0][0][0];
Scanner sf = new Scanner(new File("path/matrices.txt"));
int matrix = -1;
int row = -1;
int column = -1;
while (sf.hasNext()){
    String line = sf.nextLine();
    if(line.equals("matrix")) {
        //'Resize' array: Create new array with 1 more length and old data
        arrays = Arrays.copyOf(arrays, arrays.length + 1);
        //Start new matrix
        arrays[++matrix] = new String[0][0];
        row = -1;
        column = -1;
    }else if(line.equals("row")) {
        //'Resize' matrix: Create a new array with 1 more length and old data
        arrays[matrix] = Arrays.copyOf(arrays[matrix], arrays[matrix].length+1);
        row++;
        arrays[matrix][row] = new String[0];
        column = -1;
    }else{
        //'Resize' matrix
        column++;
        arrays[matrix][row] = Arrays.copyOf(arrays[matrix][row], arrays[matrix][row].length+1);
        arrays[matrix][row][column] = line;
    }
}
sf.close();

//Print result
for(int i = 0 ; i < arrays.length; i++) {
    System.out.println("Matrix "+i);
    for(int j = 0; j < arrays[i].length; j++ ) {
        for(int k = 0; k < arrays[i][j].length; k++) {
            System.out.print(arrays[i][j][k]+ " ");
        }
        System.out.println();
    }
    System.out.println();
}   

And the result is:结果是:

Matrix 0
a b c 
d e f 
g h i 
j k l 

Matrix 1
m n o p q 
r s t u v 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM