简体   繁体   English

从文本文件生成二维双精度数组

[英]Generating 2D double array from text file

I have a text file 我有一个文本文件

0.4658 0 3
0.4095 0 3
0.4594 0 3
0.4297 0 3
0.3963 0 3
0.4232 0 3
0.4633 0 3
0.5384 0 3
0.5042 0 3
0.4328 0 3

that I want to read into a 2D double array that looks like this. 我想读入一个像这样的二维双数组。

{{0.4658, 0, 3},
 {0.4095, 0, 3},
    ... (and so on)
 {0.4328, 0, 3}}

I have the following code: 我有以下代码:

public static void main(String[] args) throws Exception{
    double[][] ref = null;

    ref = matrix("data80.in",10,3);

 }

public static double[][] matrix(String filename, int size1, int size2) throws Exception {
    double[][] matrix = null;

    BufferedReader buffer = new BufferedReader(new FileReader(filename));

    String line;
    int row = 0;

    while ((line = buffer.readLine()) != null) {
        String[] vals = line.trim().split("\\s+");


        if (matrix == null) {
            matrix = new double[size1][size2];
        }

        for (int col = 0; col < size1; col++) {
            matrix[row][col] = Double.parseDouble(vals[col]);
        }

        row++;
    }
    buffer.close();
    return matrix;
}

But it keeps giving me an outOfBounds exception, and I don't know where I am going wrong. 但是它一直给我一个outOfBounds异常,而且我不知道我要去哪里。 Please help. 请帮忙。 If anyone has more efficient solutions as well to my problem it would be helpful 如果有人对我的问题也有更有效的解决方案,那将是有帮助的

You have defined you 2d matrix as 您已将2d矩阵定义为

matrix = new double[size1][size2];

meaning there are size1 rows and size2 columns but in following line: 意思是在下面的行中有size1行和size2列:

for (int col = 0; col < size1; col++) {

you have used size1 . 您已经使用过size1 So correction is: 因此更正为:

for (int col = 0; col < size2; col++) {

It's because of the following for loop: 这是因为以下for循环:

for (int col = 0; col < size1; col++) {
   matrix[row][col] = Double.parseDouble(vals[col]);
}

We are using size1 whereas we should be using size2 , following would work: 我们正在使用size1而我们应该使用size2 ,则可以使用以下代码:

for (int col = 0; col < size2; col++) {
   matrix[row][col] = Double.parseDouble(vals[col]);
}

Also, there is no need for null check inside the for loop, you can remove it and initialise the array in the beginning, eg: 同样,也不需要在for循环内进行null检查,您可以将其删除并在开始时初始化array ,例如:

public static double[][] matrix(String filename, int size1, int size2) throws Exception {
    double[][] matrix = new double[size1][size2];;

    BufferedReader buffer = new BufferedReader(new FileReader(filename));

    String line;
    int row = 0;

    while ((line = buffer.readLine()) != null) {
        String[] vals = line.trim().split("\\s+");


        for (int col = 0; col < size2; col++) {
            matrix[row][col] = Double.parseDouble(vals[col]);
        }

        row++;
    }
    buffer.close();
    return matrix;
}

Here is yet another concept as to how you can place the delimited numerical data contained within a text file of any number of rows and any number of columns into a Double data type Two Dimensional Array. 关于如何将文本文件中包含的定界数字数据放置在任意数量的行和任意列的文本文件中,这又是一个概念,它可以放入Double数据类型“二维数组”中。 All you need to do is pass the path and file name to the method. 您需要做的就是将路径和文件名传递给方法。 You can also optionally supply the delimiter used within the file, the method default is a comma (,) delimiter since it is one of the most commonly used. 您还可以选择提供文件中使用的定界符,方法默认为逗号(,)定界符,因为它是最常用的定界符之一。 Here is the method: 方法如下:

public static double[][] matrix(String filename, String... delimiterInFile) {
    String delimiter = ","; // Default data delimiter in file.
    // See if a optional data delimiter is supplied...
    if (delimiterInFile.length > 0) { delimiter = delimiterInFile[0]; }

    // Catch IO Exceptions
    try {
        //Place the contents of file into a ArrayList
        List<String> list = Files.lines(Paths.get(filename)).collect(Collectors.toList());

        // Get the greatest number of delimited columns contiained 
        // within the ArrayList the whole while ignoring blank lines
        // (there could be blank lines in file). Our columns for our
        // double 2D Array will be determined from this value. We also 
        // determine the true number of rows required (remember, no
        // blank elements allowed so ArrayList.size() wont be good enough).
        int r = 0, c = 0;
        for (int i = 0; i < list.size(); i++) {
            if (!list.get(i).equals("")) {
                int l = list.get(i).split(delimiter).length;
                if (l > c) { c = l; }
                r++;
            }
        }

        // If we have nothing then the get outta here 
        // by returning null.
        if (r == 0 || c == 0) { return null; }

        // Declare and initialize a double data type 2D Array
        double[][] array = new double[r][c];

        // Fill the double type array...
        for (int i = 0; i < list.size(); i++) {
            if (!list.get(i).equals("")) {
                String[] data = list.get(i).split(delimiter);
                for (int j = 0; j < data.length; j++) {
                    array[i][j] = Double.parseDouble(data[j]);
                }
            }
        }
        return array;
    } catch (IOException ex) { 
        // Do what you want with the Exception...
        ex.printStackTrace();
        return null;
    }
}

This method will automatically determine the required number of Rows and Columns for the returned Double data type 2D Array. 此方法将自动为返回的Double数据类型2D数组确定所需的行数和列数。 The method ignores blank file lines so the required Rows needed for the returned Double 2D Array is determined with this in mind. 该方法会忽略空白文件行,因此在确定返回的Double 2D数组所需的行数时会考虑到这一点。 The number of Columns value is determined by iterating through the data lines and detecting which data line contains the most delimited data. 列数值是通过遍历数据线并检测哪个数据线包含分隔的数据来确定的。 That column count is used for the entire 2D Array. 该列数用于整个2D阵列。 This means then that file data lines which contain less columns will have their remaining Array Elements filled with a 0.0 double type value. 这意味着,包含较少列的文件数据行将使用0.0双重类型值填充剩余的数组元素。

The optional delimiter that can be passed to this method can be any string or a RegEx ( Regular Expression ) string, for example: " " or "\\\\s+" or "," or ", " or "\\t" , etc. 可以传递给此方法的可选定界符可以是任何字符串或RegEx( 正则表达式 )字符串,例如: " ""\\\\s+"","", ""\\t"等。

This method will also throw an IO Exception should there be a problem accessing the supplied data file. 如果访问提供的数据文件有问题,此方法也会引发IO异常

With the data file schema you provided: 使用您提供的数据文件模式:

0.4658 0 3
0.4095 0 3
0.4594 0 3
0.4297 0 3
0.3963 0 3
0.4232 0 3
0.4633 0 3
0.5384 0 3
0.5042 0 3
0.4328 0 3

and let's assume this file is named data.txt which is in your classpath , you might use this method like this: 并假设该文件名为data.txt ,它位于您的类路径中 ,您可以使用以下方法:

double[][] myData = matrix("data.txt", "\\s+");
for (int i = 0; i < myData.length; i++) {
    String strg = "";
    for (int j = 0; j < myData[0].length; j++) {
         strg+= myData[i][j] + " ";
    }
    System.out.println(strg);
}

Keep in mind, this is not a method I would recommend for really large data files (Hundreds of thousands of lines). 请记住,对于真正的大数据文件(数十万行),我不建议使用这种方法。

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

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