Digamos que el argumento de cadena pasado por la persona que llama original es de longitud N.
Finalmente, el argumento de cadena que ingresa a este método tendrá un carácter de longitud, el caso N = 1. En ese caso, esta rutina devuelve “y” o la cadena en sí. (Se invoca solo una vez más con una cadena vacía, el caso N = 0. Inmediatamente recupera la cadena vacía, la concatena al carácter sin efecto y luego devuelve el carácter).
Tan pronto como lo haga, el control vuelve a la declaración de retorno en el cuadro de la pila inmediatamente encima de él, lo que hace la concatenación de cadenas y devuelve el control al siguiente cuadro más alto, y así sucesivamente, hasta que ascienda N cuadros y llegue a la persona que llama original. Si observa lo que está haciendo el hilo, está llamando a substring () N veces (un método eficiente que no implica la copia de matrices) en su camino hacia abajo. Toca el caso N = 0, y luego realiza una serie de concatenaciones de cadenas ineficientes en su camino de regreso.
- Si tengo una base de datos con 100 mil millones de nombres de usuario, ¿cómo construyo eficientemente una matriz ordenada a partir de eso para realizar fácilmente una búsqueda binaria?
- Si existen múltiples rutas más cortas entre 2 nodos en un gráfico no dirigido, ¿es posible imprimirlas todas utilizando el algoritmo de Dijkstra?
- ¿Debería usar la función de clasificación () incorporada de C ++ para problemas en la programación competitiva, o debería implementar el algoritmo por mi cuenta?
- ¿Cuál es el algoritmo de clasificación menos eficiente?
- ¿Es posible elegir aleatoriamente un número de (0 a infinito), de modo que cada número tenga la misma probabilidad de ser elegido?
Si en una entrevista le piden que invente una rutina que reemplace “x” con “y”, y escriba basura como esta en una pizarra, lo expulsarán con spray de pimienta, por varias razones:
- La JVM solo permite una profundidad de pila de 256 niveles de profundidad. Si se pasa una cadena de más de 250 caracteres, este código arrojará un StackOverflowError.
- Las cadenas en Java son inmutables, por lo que el operador de concatenación tiene que generar una nueva cadena un poco más larga para cada marco de pila. Esto implica la copia de la matriz y la huella de memoria aumenta como O (N ^ 2). Sin embargo, esto probablemente no será un problema, porque la concatenación solo ocurre después de la llamada más profunda, y el StackOverflowError lo atrapará primero. Como máximo, generará 64K de basura por invocación. [Aunque en esta implementación particular, el recolector de basura podrá perseguir su hilo a medida que asciende de nuevo por la pila. Pero no hay razón para que haga tanto trabajo.]
- Las dos primeras declaraciones if son ambas protecciones para el caso de cadena vacía. Solo necesitas uno. Eliminar uno de ellos o la gente perderá el tiempo entrecerrando los ojos y preguntándose qué estaba pensando.
- Es difícil mirar un artilugio ofuscado como este y no detectar un elemento de malicia.
- Lo peor de todo, esta funcionalidad ya está implementada en la API de Java. Nadie quiere pagarte por el tiempo que pasas reescribiéndolo mal.
Aquí hay tres formas (no probadas) de reescribir este código que mitigan o evitan estos problemas:
1. Si realmente debe usar la recursión, al menos divida la cadena en * mitad * al final, de modo que la profundidad de la pila aumente solo logarítmicamente con respecto a la longitud de la cadena, y la memoria solo aumente a medida que O (N * log (N)). Esto también es estúpido, pero al menos no se romperá:
int halfMeasure = str.length () / 2;
return changeXY (str.substring (0, halfMeasure))
+ changeXY (str.substring (halfMeasure, str.length ()));
2. Utilice un StringBuilder, StringBuffer o char [], y evite por completo tanto la recursividad como el ineficiente operador de concatenación de cadenas de Java. Si bien StringBuffer / StringBuilder está diseñado para estos fines, si solo está reemplazando un solo carácter con otro, puede usar un carácter []:
public String changeXY (String str) {
char [] result = new char [str.length ()];
for (int j = 0; j <str.length (); j ++) {
char c = str.charAt (j);
resultado [j] = c === ‘x’? ‘y’: c;
}
devolver nueva cadena (resultado);
}
3. Codifique como una persona normal:
public String changeXY (String str) {
return str.replace (‘x’, ‘y’);
}