Leer matrices no regulares

Ya era lo único que me faltaba por preguntar... Leer una matriz no regular. He pensado en indicar las dimensiones al principio del archivo como me recomendaste, no hay ningún problema. Te dejo el que habías hecho para regulares, porque seguro que algo sirve...
Muchísimas gracias!
import java.io.*;
import java.util.StringTokenizer;
public class Leer {
public static void main(String[] args) {
if (args.length == 1)
printm(porLineas(args[0]));
}
public static void printm(Object[][] mat) {
for (int i = 0; i < mat.length; ++i) {
for (int j = 0; j < mat.length; ++j)
System.out.print(mat[j] + " ");
System.out.println();
}
}
public static Object[][] porLineas(String ruta) {
try {
FileReader arch = new FileReader(ruta); // Lector de archivo
BufferedReader buff = new BufferedReader(arch); // Buffer de lectura
// Calcular el orden de la matriz y reservar espacio
String linea = buff.readLine();
StringTokenizer st = new StringTokenizer(linea);
int orden = st.countTokens();
Object[][] mat = new Object[orden][orden];
// Rellenar la matriz
for (int i = 0; i < orden; ++i) {
for (int j = 0; j < orden; ++j)
mat[j] = st.nextToken();
/* La primera linea ya fue leída (para calcular las dimensiones),
así que ahora solo hay que leer las n - 1 siguientes. */
if (i < orden - 1) {
linea = buff.readLine();
st = new StringTokenizer(linea);
}
}
// Mostrar datos sobre la matriz
System.out.println("Matriz de orden " + orden);
// Otros datos
// Cerrar los flujos de entrada
buff.close();
arch.close();
// Salir
return mat;
}
catch (IOException ioe) {
System.out.println(ioe);
return null;
}
}
}
Respuesta
1
Incluyendo las dimensiones de la matriz al principio del archivo, el programa queda más sencillo y el método más elegante, ya que no hay que calcular el orden de dicha matriz a partir del número de tokens de la primera línea.
Asumo que la sintaxis del archivo es:
M n
a11 a12 ... a1n
a21 a22 ... a2n
... ... ... ...
am1 am2 ... amn
Es decir: en la primera línea, las dimensiones; y, debajo, la matriz como tal. Lo único que cambiaría ahora sería el método porLineas, que seguiría los siguientes pasos:
1. Abrir el archivo
2. Leer las dimensiones de la matriz
3. Reservar espacio para los datos
4. Rellenar el array
5. Cerrar los flujos de entrada
6. Devolver la referencia a la matriz
El código sería, por tanto, el siguiente:
public static Object[][] porLineas(String ruta) {
try {
FileReader arch = new FileReader(ruta); // Lector de archivo
BufferedReader buff = new BufferedReader(arch); // Buffer de lectura
// Calcular las dimensiones de la matriz y reservar espacio
String linea = buff.readLine();
StringTokenizer st = new StringTokenizer(linea);
int nFil = Integer.parseInt(st.nextToken());
int nCol = Integer.parseInt(st.nextToken());
Object[][] mat = new Object[nFil][nCol];
// Rellenar la matriz
for (int i = 0; i < nFil; ++i) {
linea = buff.readLine();
st = new StringTokenizer(linea);
for (int j = 0; j < nCol; ++j)
mat[j] = st.nextToken();
}
// Mostrar datos sobre la matriz
System.out.println("Dimensiones: " + nFil + "x" + nCol);
// Otros datos
// Cerrar los flujos de entrada
buff.close();
arch.close();
// Salir
return mat;
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
Si hay alguna parte que no entiendes, no dudes en preguntarme. ¡Suerte!
He entendido el código, el problema es que esta parte (leer ficheros) la tengo que insertar dentro de un programa que ya tengo hecho. En él las matrices las tengo todas definidas como int[][] y todos los métodos leen int[][]. He intentado cambiar la definición de mat pero por más vueltas que le doy no consigo que funcione, a la hora de rellenar la matriz da un error. El código para leer matrices cuadradas lo había modificado y no me dio problemas... no sé que puede ser
En tu caso se trata de cambiar más tipos de datos aparte del de la variable mat, y utilizar la función estática parseInt de la clase Integer para hacer conversiones de cadenas de caracteres a valores enteros.
El código completo sería el siguiente:
import java.io.*;
import java.util.StringTokenizer;
public class Leer {
public static void main(String[] args) {
if (args.length == 1)
printm(porLineas(args[0]));
}
public static void printm(int[][] mat) {
for (int i = 0; i < mat.length; ++i) {
for (int j = 0; j < mat.length; ++j)
System.out.print(mat[j] + " ");
System.out.println();
}
}
public static int[][] porLineas(String ruta) {
try {
FileReader arch = new FileReader(ruta); // Lector de archivo
BufferedReader buff = new BufferedReader(arch); // Buffer de lectura
// Calcular las dimensiones de la matriz y reservar espacio
String linea = buff.readLine();
StringTokenizer st = new StringTokenizer(linea);
int nFil = Integer.parseInt(st.nextToken());
int nCol = Integer.parseInt(st.nextToken());
int[][] mat = new int[nFil][nCol];
// Rellenar la matriz
for (int i = 0; i < nFil; ++i) {
linea = buff.readLine();
st = new StringTokenizer(linea);
for (int j = 0; j < nCol; ++j)
mat[j] = Integer.parseInt(st.nextToken());
}
// Mostrar datos sobre la matriz
System.out.println("Dimensiones: " + nFil + "x" + nCol);
// Otros datos
// Cerrar los flujos de entrada
buff.close();
arch.close();
// Salir
return mat;
}
catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
Ahora la función devuelve una matriz de enteros que, igual que la anterior, puede mostrarse en pantalla cuando se pasa como argumento a la función printm().

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas