Matrices

Objetivos:

Temas:


Azúcar sintáctico

Algunos de los patrones de programación se repiten tan frecuentemente que los lenguajes de programación incluyen formas sintácticas que son abreviaciones para estos patrones. El único objetivo de estas abreviaciones es brindar un mecanismo para escribir menos código:

Ejemplo: cálculo del factorial.

    double fact(int n) {
      int i;
      double f= 1;
      for (i=1; i<=n; i++)
        f= f*i;
      return f;
    }

El tipo de datos matriz

Las matrices son un caso especial de arreglos. Se distinguen de los arreglos tradicionales en que se especifican 2 índices en vez de uno. Las operaciones que se pueden realizar con una matriz son:

Ejemplo Significado Sintaxis
double[][] m= new double[n][p]; Construye una matriz de n x p new tipo[filas][cols]
m[i][j]= 5.2; Almacena 5.2 en la fila i, columna j matriz[fila][col]
double x= m[i][j]; entrega el valor almacenado en i,j matriz[fila][col]= exp;

Para leer una matriz 10 x 20 se usa:

    int n= 10;
    int p= 20;
    TextReader lect= new TextReader("matriz.dat");
    double[][] m= new double[n][p];
    for (int i= 0; i<n; i++)
      for (int j= 0; j<p; j++)
        m[i][j]= lect.readDouble();
El mismo patrón se puede usar para escribir la matriz. Es muy importante darse cuenta que el patrón anterior recorre la matriz por filas. Es decir que el archivo debe contener primero los valores para la primera fila, luego los valores para la segunda fila, etc.

El siguiente código despliega el contenido de la matriz pero por columnas:

    for (int j= 0; j<p; j++)
      for (int i= 0; i<n; i++)
        print(m[i][j]);
Primero despliega la primera columna, luego la segunda, etc. Por supuesto el programa debería colocar las columnas en distintas líneas:

    for (int j= 0; j<p; j++) {
      for (int i= 0; i<n; i++)
        print(m[i][j]);
      println();
    }

Multiplicación de matrices

Supongamos que tenemos dos matrices a y b de n x p y de p x q respectivamente. Podemos calcular c= a*b, de n x q, mediante:

    double c= new double[n][q];
    for (int i= 0; i<n; i++)
      for (int j= 0; j<q; j++) {
        c[i][j]= 0.0;
        for (int k= 0; k<p; k++)
          c[i][j]+= a[i][k]*b[k][j];
      }

El buscaminas

Este juego consiste en descubrir donde se encuentran las minas en un campo minado. El diálogo debe ser:

    Nro. de filas ? 3
    Nro. de columnas ? 3
    Nro. de minas ? 1
    fila ? 1
    columna ? 1
    Minas adyacentes: 1
    fila ? 1
    columna ? 0
    Minas adyacentes: 0
    fila ? 0
    columna ? 1
    Minas adyacentes: 1
    fila ? 2
    columna ? 1
    Minas adyacentes: 0
    fila ? 0
    columna ? 2
    Booooom! perdiste.
Solución: el diálogo.

    print("Nro. de filas ? ");
    int nfil= readInt();
    print("Nro. de columnas ? ");
    int ncol= readInt();
    print("Nro. de minas ? ");
    int nmin= readInt();
    int[][] mat= consCampo(nfil, ncol, nmin);
    while (true) {
      print("fila ? ");
      int fil= readInt();
      print("columna ? ");
      int col= readInt();
      if (mat[fil][col]==1) {
        println("Booooom! perdiste.");
        break;
      }
      println("Minas adyacentes: "+contarMinas(mat, nfil, ncol, fil, col));
    }
La función que construye el campo minado:

    int[][] consCampo(int nfil, int ncol, int nmin) {
      int[][] mat= new int[nfil][ncol];
      for (int n=0; n<nmin; n++) {
        int i= trunc(random()*nfil);
        int j= trunc(random()*ncol);
        mat[i][j]= 1;
      }
      return mat;
    }
La función que cuenta cuantas minas se encuentran adyacentes a las coordenadas (fil, col):

  int contarMinas(int[][] mat, int nfil, int ncol, int fil, int col) {
    int cont= 0;
    for (int i= fil-1; i<=fil+1; i++)
      for (int j= col-1; j<=col+1; j++)
        if (i>=0 && i<nfil && j>=0 && j<ncol)
          cont+= mat[i][j];
    return cont; // -mat[fil][col]
  }
(Ver el programa completo en BuscaMinas.java.)

Propuesto: