Invertir una cadena (Serie Algoritmos - Parte 2)

Ariel Alvarado | Agosto 11, 2020


Este es un problema con cadenas, simplemente se debe invertir una cadena. Ejemplos:

  • "" -> ""
  • "asd" -> "dsa"
  • "abcde" -> "edcba"
  • "asdsa" -> "asdsa"

Primero crearemos los test necesarios. Idealmente comenzamos con tests más simples de realizar (en nuestro caso el test más simple es la cadena vacia). Por suerte, para este problema en particular tenemos varios ejemplos que podemos convertir en tests:

invertir.js
const assert = require("assert").strict;

const invertir = cadena => {
  return cadena;
};

assert.strictEqual(invertir(""), "");
assert.strictEqual(invertir("asd"), "dsa");
assert.strictEqual(invertir("abcde"), "edcba");
assert.strictEqual(invertir("asdsa"), "asdsa");

Antes de pasar a la solución, puedes darte un tiempo para intentar resolver el problema.

Solución 1

Mi primera forma de ver el problema es que se necesita recorrer toda la cadena y simplemente ir concatenando de manera inversa. Veamos:

invertir.js
const assert = require("assert").strict;

const invertir = cadena => {
  let resultado = "";
  // recorremos  la cadena desde la posición 0 hasta la longitud de la cadena (como el índice comienza en 0, la comparación se realiza con <)
  for (let pos = 0; pos < cadena.length; pos++) {
    // obtenemos el caracter actual
    const caracterActual = cadena.charAt(pos);
    // concatenamos el caracter al resultado
    resultado = caracterActual + resultado;
  }
  return resultado;
};

assert.strictEqual(invertir(""), "");
assert.strictEqual(invertir("asd"), "dsa");
assert.strictEqual(invertir("abcde"), "edcba");
assert.strictEqual(invertir("asdsa"), "asdsa");

Solución 2

Utilizamos algunas funciones incluidas en javascript para resolver el problema. Primero convertimos a un array, invertimos, convertimos a cadena nuevamente.

invertir2.js
const assert = require("assert").strict;

const invertir = cadena => {
  // separamos la cadena con split, esto nos devuelve un array
  const cadenaComoArray = cadena.split("");
  // invertimos el array con reverse
  const cadenaComoArrayInvertida = cadenaComoArray.reverse();
  // unimos nuevamente el array con join
  const resultado = cadenaComoArrayInvertida.join("");
  return resultado;
};

assert.strictEqual(invertir(""), "");
assert.strictEqual(invertir("asd"), "dsa");
assert.strictEqual(invertir("abcde"), "edcba");
assert.strictEqual(invertir("asdsa"), "asdsa");

Ahora, lo mismo pero encadenando las llamadas:

invertir2.js
const assert = require("assert").strict;

const invertir = cadena => {
  // separamos la cadena con split, esto nos devuelve un array
  // invertimos el array con reverse
  // unimos nuevamente el array con join
  return cadena.split("").reverse().join("");
};

assert.strictEqual(invertir(""), "");
assert.strictEqual(invertir("asd"), "dsa");
assert.strictEqual(invertir("abcde"), "edcba");
assert.strictEqual(invertir("asdsa"), "asdsa");

Conclusión

Primero y más importante, ninguna de las maneras es mejor o peor, simplemente son maneras diferentes de realizar una tarea.

En mi opinión, la forma que sea más entendible es la que debe utilizarse (tanto en problemas simples como complejos) y solamente se debe optimizar por velocidad en caso de ser necesario.

Nota: La solución más veloz es la segunda, puedes utilizar cualquier herramienta que mida el performance para verificar que no miento xD. Puedes realizar las pruebas en línea con https://perf.link/