Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
291 views
in Technique[技术] by (71.8m points)

java - Read .txt file into 2D Array

There are a few of these topics out there, but this problem has a slight twist that makes it different.

I'm focused on only half of a larger problem. I'm sure many of you are aware of the magic square problem.

Prompt:
Assume a file with lines and numbers on each line like the square shown. Write a program that reads info into a two dimensional array of intS. The program should determine if the matrix is a magic square or not.

Working Solution:

public static int[][] create2DIntMatrixFromFile(String filename) throws Exception {
int[][] matrix = {{1}, {2}};

File inFile = new File(filename);
Scanner in = new Scanner(inFile);

int intLength = 0;
String[] length = in.nextLine().trim().split("\s+");
  for (int i = 0; i < length.length; i++) {
    intLength++;
  }

in.close();

matrix = new int[intLength][intLength];
in = new Scanner(inFile);

int lineCount = 0;
while (in.hasNextLine()) {
  String[] currentLine = in.nextLine().trim().split("\s+"); 
     for (int i = 0; i < currentLine.length; i++) {
        matrix[lineCount][i] = Integer.parseInt(currentLine[i]);    
            }
  lineCount++;
 }                                 
 return matrix;
}


public static boolean isMagicSquare(int[][] square) {

  return false;
}

Here is my (old) code for reading info from a text file into a 2D array:

public static int[][] create2DIntMatrixFromFile(String filename) throws Exception {
    int[][] matrix = {{1}, {2}};
    File inFile = new File(filename);
    Scanner in = new Scanner(inFile);
    in.useDelimiter("[/n]");

    String line = "";
    int lineCount = 0;

    while (in.hasNextLine()) {
        line = in.nextLine().trim();
        Scanner lineIn = new Scanner(line);
        lineIn.useDelimiter("");

        for (int i = 0; lineIn.hasNext(); i++) {
            matrix[lineCount][i] = Integer.parseInt(lineIn.next());
            lineIn.next();
        }

        lineCount++;
    }

    return matrix;
}

public static boolean isMagicSquare(int[][] square) {
    return false;
}

And here is the text file I am reading from. It is in the shape of a 9x9 2D array, but the program must accommodate an array of ambiguous size.

  37  48  59  70  81   2  13  24  35 
  36  38  49  60  71  73   3  14  25 
  26  28  39  50  61  72  74   4  15 
  16  27  29  40  51  62  64  75   5 
   6  17  19  30  41  52  63  65  76 
  77   7  18  20  31  42  53  55  66 
  67  78   8  10  21  32  43  54  56 
  57  68  79   9  11  22  33  44  46 
  47  58  69  80   1  12  23  34  45 

There are two spaces proceeding each line on purpose.

Before I state the exact problem, this is a homework template so the method declaration and variable initialization was pre-determined.

I'm not positive that the method even correctly creates a 2D Array from the file because I can't run it yet. The issue is that for some reason "matrix" was initialized with 1 column and 2 rows. For what reason I'm not sure, but in order to fill an array with the numbers from the file I need to create a 2D array with dimensions equal to the number of values in a line.

I previously had written code to create a new 2D array

int[line.length()][line.length()]

but it created a 36x36 array because that's how many individual characters are in one line. I have a feeling it's as simple as looping through the first line and having a counter keep track of each sequence of numbers separated by a zero.

To me, that solution seems too inefficient and time consuming just to find the dimensions of the new array. What's the best way to accomplish this? Without using ArrayLists as I have to rewrite this program after using ArrayLists.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I produced the following 2D array from the file you provided:

 37 | 48 | 59 | 70 | 81 |  2 | 13 | 24 | 35
----+----+----+----+----+----+----+----+----
 36 | 38 | 49 | 60 | 71 | 73 |  3 | 14 | 25
----+----+----+----+----+----+----+----+----
 26 | 28 | 39 | 50 | 61 | 72 | 74 |  4 | 15
----+----+----+----+----+----+----+----+----
 16 | 27 | 29 | 40 | 51 | 62 | 64 | 75 |  5
----+----+----+----+----+----+----+----+----
  6 | 17 | 19 | 30 | 41 | 52 | 63 | 65 | 76
----+----+----+----+----+----+----+----+----
 77 |  7 | 18 | 20 | 31 | 42 | 53 | 55 | 66
----+----+----+----+----+----+----+----+----
 67 | 78 |  8 | 10 | 21 | 32 | 43 | 54 | 56
----+----+----+----+----+----+----+----+----
 57 | 68 | 79 |  9 | 11 | 22 | 33 | 44 | 46
----+----+----+----+----+----+----+----+----
 47 | 58 | 69 | 80 |  1 | 12 | 23 | 34 | 45

The array figures out the size of the square when it reads the first line of the file. This is very dynamic. Its works as long as the input file is a perfect square. I have no further error handling.

Here is a simple approach which should adhere to your guidelines.

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class ReadMagicSquare {
    public static int[][] create2DIntMatrixFromFile(String filename) throws Exception {
        int[][] matrix = null;

        // If included in an Eclipse project.
        InputStream stream = ClassLoader.getSystemResourceAsStream(filename);
        BufferedReader buffer = new BufferedReader(new InputStreamReader(stream));

        // If in the same directory - Probably in your case...
        // Just comment out the 2 lines above this and uncomment the line
        // that follows.
        //BufferedReader buffer = new BufferedReader(new FileReader(filename));

        String line;
        int row = 0;
        int size = 0;

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

            // Lazy instantiation.
            if (matrix == null) {
                size = vals.length;
                matrix = new int[size][size];
            }

            for (int col = 0; col < size; col++) {
                matrix[row][col] = Integer.parseInt(vals[col]);
            }

            row++;
        }

        return matrix;
    }

    public static void printMatrix(int[][] matrix) {
        String str = "";
        int size = matrix.length;

        if (matrix != null) {
            for (int row = 0; row < size; row++) {
                str += " ";
                for (int col = 0; col < size; col++) {
                    str += String.format("%2d",  matrix[row][col]);
                    if (col < size - 1) {
                        str += " | ";
                    }
                }
                if (row < size - 1) {
                    str += "
";
                    for (int col = 0; col < size; col++) {
                        for (int i = 0; i < 4; i++) {
                            str += "-";
                        }
                        if (col < size - 1) {
                            str += "+";
                        }
                    }
                    str += "
";
                } else {
                    str += "
";
                }
            }
        }

        System.out.println(str);
    }

    public static void main(String[] args) {
        int[][] matrix = null;

        try {
            matrix = create2DIntMatrixFromFile("square.txt");
        } catch (Exception e) {
            e.printStackTrace();
        }

        printMatrix(matrix);
    }
}

This approach is more refined and optimized.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class ReadMagicSquare {

    private int[][] matrix;
    private int size = -1;
    private int log10 = 0;
    private String numberFormat;

    public ReadMagicSquare(String filename) {
        try {
            readFile(filename);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void readFile(String filename) throws IOException {
        // If included in an Eclipse project.
        InputStream stream = ClassLoader.getSystemResourceAsStream(filename);
        BufferedReader buffer = new BufferedReader(new InputStreamReader(stream));

        // If in the same directory - Probably in your case...
        // Just comment out the 2 lines above this and uncomment the line
        // that follows.
        //BufferedReader buffer = new BufferedReader(new FileReader(filename));

        String line;
        int row = 0;

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

            // Lazy instantiation.
            if (matrix == null) {
                size = vals.length;
                matrix = new int[size][size];
                log10 = (int) Math.floor(Math.log10(size * size)) + 1;
                numberFormat = String.format("%%%dd", log10);
            }

            for (int col = 0; col < size; col++) {
                matrix[row][col] = Integer.parseInt(vals[col]);
            }

            row++;
        }
    }

    @Override
    public String toString() {
        StringBuffer buff = new StringBuffer();

        if (matrix != null) {
            for (int row = 0; row < size; row++) {
                buff.append(" ");
                for (int col = 0; col < size; col++) {
                    buff.append(String.format(numberFormat,  matrix[row][col]));
                    if (col < size - 1) {
                        buff.append(" | ");
                    }
                }
                if (row < size - 1) {
                    buff.append("
");
                    for (int col = 0; col < size; col++) {
                        for (int i = 0; i <= log10 + 1; i++) {
                            buff.append("-");
                        }
                        if (col < size - 1) {
                            buff.append("+");
                        }
                    }
                    buff.append("
");
                } else {
                    buff.append("
");
                }
            }
        }

        return buff.toString();
    }

    public static void main(String[] args) {
        ReadMagicSquare square = new ReadMagicSquare("square.txt");
        System.out.println(square.toString());
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...