Estoy trabajando en una solución en Java que elimina una fila si una de las celdas contiene NULL, como una fila con el nombre Jenny. La tabla se proporciona en formato CSV. Cada dos celdas consecutivas en cada fila están separadas por una sola coma ',' símbolo. Cada dos filas consecutivas están separadas por un símbolo de nueva línea '\n'. Por ejemplo, la tabla de la declaración de la tarea, escrita en formato CSV, es una sola cadena:
"id,name,age,score\n1,Jack,NULL,12\n17,Betty,28,11".Puede suponer que cada fila tiene el mismo número de celdas. Es necesario tener cuidado con palabras como 'ANULADO'.
S = "id,name,age,score\n1,Jenny,NULL,14\n17,Daryll,31,11" , su función debería devolver "id,name,age,score\n17,Betty,28,11" . +----+-------+------+-------+ | id | name | age | score | +----+-------+------+-------+ | 1b | Jenny | NULL | 14 | +----+-------+------+-------+ | 17 | Daryll| 32 | 11 | +----+-------+------+-------+Mi solución ha sido marcada como solo 33 de 100 en cuanto a eficiencia y me pregunto si alguien podría aconsejarme cómo puedo mejorar mi solución, por favor.
public static void main(String[] args) { String S = "id,name,age,score\n1,Jack,NULL,12\n17,Betty,28,11"; System.out.println(solution(S)); } public static String solution(String S) { ArrayList<String> al = new ArrayList<String>(); String[] rows = S.split("\n"); String finalString = ""; for (int i = 0; i < rows.length; i++) { al.add(rows[i]); } for (int i = 0; i < al.size(); i++) { if (al.get(i).contains(",NULL,") || al.get(i).contains("NULL\n") || al.get(i).contains(",NULL")) { al.remove(i); } } for (int i = 0; i < al.size(); i++) { finalString += al.get(i) + "\n"; } String finalerString = finalString.substring(0, finalString.length() - 1); return finalerString; }En términos de eficiencia, la solución más eficiente sería iterar sobre la cadena de entrada, S una vez y escribir la solución en una secuencia. Ahora vamos a compararlo con su implementación.
S.split("\n"); requiere una iteración completa sobre el pulso S , crea memoria adicional del tamaño de Sal.add(rows[i]); convierte la matriz String a List, no veo ninguna necesidad de eso, pero no creo que afecte mucho el rendimiento.al.get(i).contains(",NULL,") que itera sobre toda la cadena, y tiene tres de esas condiciones, por lo que itera sobre S tres veces aquí (en el peor de los casos, ya que si la primera or la condición es verdadera los demás no serán revisados).finalString += al.get(i) + "\n"; Aquí está reconstruyendo la solución sin las filas filtradas. El problema con += en String s es que cada vez crea una nueva instancia de String . Esto hace que su implementación sea O(N^2) en lugar de O(N) . Cambie a StringBuilder y volverá al espacio O(N) . Con ADE moderno como IntelliJ, recibirá una advertencia y actualizará su código automáticamente.finalString.substring(0, finalString.length() - 1); Nuevamente, aquí está creando una nueva instancia de String, por lo que le cuesta SPara implementar una solución simple y eficiente, haría lo siguiente
S por \n como lo hicisteNullStringBuilder para combinar los resultadosPara el filtrado haría algo como:
al.get(i).startsWith("NULL\n") || al.get(i).endsWith(",NULL") || al.get(i).contains(",NULL,") Los métodos startsWith , endsWith son O(1) en comparación con contains que es O(N) , por lo que el filtrado será O(1) en el mejor de los casos y O(N) en el peor de los casos.
Como dije antes, esta no será la solución más eficiente, pero es bastante simple y bastante eficiente. Requiere solo dos iteraciones sobre S en el peor de los casos.
La forma más eficiente de hacer esto es simplemente trabajar en la forma de cadena.
Aquí se explica cómo realizar la operación solicitada con una expresión regular, que admito que no es la forma más eficiente de trabajar en la cadena, pero aún así no debería ser tan mala:
import java.util.regex.Pattern; class Test { public static void main(String[] args) { String data = "id,name,age,score\n1,Jenny,NULL,14\n17,Daryll,31,11"; Pattern exp = Pattern.compile("^(.*,)*NULL(,.*)*(\\n|$)", Pattern.MULTILINE); String r = exp.matcher(data).replaceAll(""); System.out.println(r); } }No soy mucho de un weenie de expresiones regulares. Es probable que haya una expresión regular más concisa que esta, pero esto le da una idea y funciona.
Resultado:
id,name,age,score 17,Daryll,31,11