Convert String to matrix

1

I have this string in Java

String str = "a, b, c, d, e, f, g, h, i, j, k, l, m, , n, o, p";

And I need to convert it into a matrix where the rows and columns are specified. That is:

3 by 3

a b c
d e f
g h i

O

2 for 8

a  b  c  d  e  f  g  i
j  k  l  m  n  o  p  q 

This is my code, which always returns null

public static String Format(String str, int rows, int columns)
    {
        try
        {
            String[][] matrix = new String[rows][columns];
            String[][] arr = Arrays.stream(str.substring(2, str.length() - 2).split("\],\["))
            .map(e -> Arrays.stream(e.split("\s*,\s*"))
            .toArray(String[]::new)).toArray(String[][]::new);

            String append = "|\t", result;

             for (int i = 0; i < rows; ++i) 
             {
                for (int j = 0; j < columns; ++j) 
                {
                    matrix[i][j] = arr[i][j];
                }
             }

              for(int i=0;i<rows;i++){
               for(int j=0;j<columns;j++){
                append += matrix[i][j] + "\t";
                }}

            result = append + "|";
            append = "|\t";
            return result;

        }
        catch(Exception e)
        {
            return null;
        }
    }
    
asked by Héctor Manuel Martinez Durán 01.04.2018 в 08:24
source

2 answers

2

It seems that the error is in how you convert the string into an array to fill the matrix, here I used a vector (one-dimensional array) I'm iterating it and if you pass the full length with *. Also the formatting of the output was half strange (append) so I set it to put a | when starting the row and a | plus a line break when closing the row

public static String FormatMatrix(String str, int rows, int columns) {
 try {
  String[][] matrix = new String[rows][columns];
  String[] arr = str.split("\s*,\s*");

  int k = 0;
  int s = arr.length;

  for (int i = 0; i < rows; ++i) {
   for (int j = 0; j < columns; ++j) {
    matrix[i][j] = (k < s) ? arr[k] : "*";
    ++k;
   }
  }

  String append = "", result;

  for (int i = 0; i < rows; ++i) {
   append += "|\t";
   for (int j = 0; j < columns; ++j) {
    append += matrix[i][j] + "\t";
   }
   append += "|\n";
  }
  result = append;
  return result;

 } catch (Exception e) {
  return null;
 }
}
    
answered by 01.04.2018 / 10:25
source
2

Now that the question has been updated to clarify, I would like to offer a slightly more elaborate answer.

I propose to use the tools that Java gives us:

  • Use a designed class that can be used and improved over time according to the requirements. In this example I created a class MatrixReader to read a string of characters and convert it into a matrix.
  • This makes it easier to check unit tests or change the design in many cases
  • Use Scanner to break down the character string easily. In general, they say that a good Java programmer knows how to use standard tools (without reinventing the wheel); I chose Scanner because it is easy to use and StringBuilder for efficiency ( String is immutable, StringBuffer is thread safe but for a simple program StringBuilder is sufficient and efficient)
  • A clearer specification is missing. The relationship between the string of characters and the matrix would have to be more detailed: What happens if I have a, b, c with a matrix of 2 x 2 ? What happens if I have a, b, c, d, e, f, g, h, i, j with an array of 2 x 6 ? (In this example the reading is finished when there are no more characters or there is no space in the matrix, see the last two matrices in the example)

I would also like to give you feedback regarding your style:

  • try/catch is a good tool to deal with exceptions but it is not a good solution in many cases that I see in Java programs. In this case, I suppose you want to avoid an exception by accessing the vector ( ArrayOutOfBoundsException ). It can be done but I am not sure if it is necessary. Simply preventing access outside the vector is sufficient (and a good spacing helps as stated before); Maybe my example can inspire you a little. try/catch is advised in situations that can not be controlled, but in this case we could in my opinion)
  • Your code always returns null for try/catch . It is the only place that returns null in its code. I hope you see that the use of try/catch is also not a solution for all situations. I wanted to avoid an exception but it costs us time now analyzing why the code does not work.
  • The use of a class String to represent a character is possible but I do not see it as effective. In my example I wanted to show that the internal repsentación (in the class) can be easier and more effective ( char ) without giving up the need to convert and / or issue in another representation ( String )

_

import java.util.*;
import java.io.*;

public class Program {

    public static void main(String[] args) {

        //Parametros
        String str = "a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p";

        //Lectura y conversion
        MatrixReader reader = new MatrixReader(str, 2, 3);
        reader.convertStringToMatrix();
        reader.printMatrix();

        reader = new MatrixReader(str, 3, 3);
        reader.convertStringToMatrix();
        reader.printMatrix();

        reader = new MatrixReader(str, 2, 8);
        reader.convertStringToMatrix();
        System.out.println("Emitir matriz " + reader.getRows() + " x " + reader.getCols());
        System.out.print(reader.getStringMatrix());

        reader = new MatrixReader(str, 3, 8);
        reader.convertStringToMatrix();
        System.out.println("Emitir matriz " + reader.getRows() + " x " + reader.getCols());
        System.out.print(reader.getStringMatrix());

        return;
    }
}

class MatrixReader {

    private String str;
    private int rows;
    private int cols;
    private char matriz[][];

    public MatrixReader(String str, int rows, int columns) {
        this.str = str;
        this.rows = rows;
        this.cols = columns;
        matriz = new char[rows][columns];
    }

    public int getCols() {
        return cols;
    }

    public int getRows() {
        return rows;
    }

    public char[][] convertStringToMatrix() {

        //Definir la cadena de caracteres a procesar y especificar el separador
        Scanner in = new Scanner(str);
        in.useDelimiter(", ");

        //llenar la matriz
        int r = 0;
        int c = 0;
        char caracter;
        //hay más carácteres para leer y estamos dentro de la matriz
        while (in.hasNext() && r < matriz.length && c < matriz[r].length) {
            caracter = in.next().charAt(0); //leer una cadena de caracteres (tamaño 1) y extraer el primer caracter
            matriz[r][c] = caracter;
            c++;
            if (c == matriz[r].length) {
                r++;
                c = 0;
            }
        }

        in.close();

        return matriz;
    }

    //emitir en salida estandar
    public void printMatrix() {
        System.out.println("Emitir matriz " + rows + " x " + cols);
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                System.out.print(" " + matriz[i][j]);
            }
            System.out.println();
        }
    }

    //convertir matriz de carácteres en cadena de carácteres
    public String getStringMatrix() {
        StringBuilder s = new StringBuilder(rows * cols);//capacidad inicial es r x c
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                s.append(' ').append(matriz[i][j]);
            }
            s.append(System.lineSeparator());//separado de línea depende del sistema
        }
        return s.toString();
    }

}
    
answered by 01.04.2018 в 19:18