Arrays paralelos
Baltasar García Perez-Schofield
Posted on September 23, 2024
El código Python que vimos en la entrada anterior para traducir a leet speech, utilizábamos un diccionario para almacenar caracteres emparejados con sus traducciones leet.
Como planteábamos, ¿qué pasa si utilizamos un lenguaje de programación como C, que no soporta diccionarios en su librería estándar?
Bien, lo primero, ¿estamos utilizando un diccionario porque realmente es lo más adecuado? En realidad, si estamos utilizando las letras del alfabeto en secuencia como claves del diccionario, solo estamos abusando de las posibilidades de Python. Al fin y al cabo, si creamos index restando de la letra que estamos buscando, el código de la primera letra del alfabeto, podemos utilizar un vector simple 'leet', es decir indexando 'leet[index]'.
Conversor leet
Por ejemplo, si tenemos ese vector leet
con el contenido de '4'
, '8'
, '('
... y '5'
y queremos buscar el código leet para la 'b'
, solo tenemos que restar 'b' - 'a'
para obtener index
con valor 1, por lo que leet[index]
devolverá '8'
.
El código a continuación implementa esto, y puede encontrarse en conversor leet en IDEOne.
def leet_from_str(s: str) -> str:
"""Converts a word or setnence to leet.
:param s: An average string.
:return: The contents of the string, converted to leet.
"""
leet_alphabet = [
"4",
"8",
"(",
"C-",
"3",
"|",
"C-",
"#",
"1",
"]",
"|<",
"|_",
"[V]",
"/V",
"0",
"|7",
"9",
"|2",
"5",
"7",
"|_|",
"\\/",
"\\N",
"><",
"'/",
"2"]
s = s.lower()
toret = ""
ord_a = ord('a')
ord_z = ord('z')
for ch in s:
ord_ch = ord(ch)
if (ord_ch >= ord_a
and ord_ch <= ord_z):
toret += leet_alphabet[ord_ch - ord_a]
else:
toret += ch
...
...
return toret
print(leet_from_str("Baltasar"))
A partir de ahora estoy utilizando código Python para evitar complejidades que pueden despistar del problema real, como por ejemplo el manejo de punteros en la solución en C para el traductor leet.
En este ejemplo, no utilizamos ninguna "clave", ya que la clave es la propia letra del abecedario. Su posición con respecto a la 'a'
nos indica la posición que debemos buscar en el leet_alphabet
.
Sin embargo, no siempre podremos "prescindir" de las claves como en este caso, pues no siempre van a resultar ser letras o dígitos correlativos. ¿Qué podemos hacer entonces?
Arrays Parelelos
Supongamos que queremos traducir del lenguaje normal al lenguaje leet. Es decir, querríamos traducir recuerda que te vas a por pan bien bueno
a recuerda k t vas a x pan bn bno
.
Estamos en este momento utilizando Python por su sencillez... de hecho, podríamos utilizar diccionarios; pero no lo haremos, porque el objetivo es ver qué se puede hacer en lenguajes que no dispongan de un soporte para ellos.
La técnica se conoce como array paralelo porque supone buscar en el vector de las claves para ver si tenemos una equivalencia. En caso de encontrarla, la posición en el vector de claves nos da la posición en el vector de elementos. De ahí que se denominen arrays paralelos.
Un ejemplo simple sería convertir los nombres originales en inglés de los personajes Pato de Disney a su equivalencia en español. Si queremos evitar un chorro de if's, entonces creamos un vector disney_en con el contenido ["mickey mouse", "donald duck", "huey", "dewey", "louie" ], y un vector disney_es con el contenido ["ratón mickey", "pato donald", "juanito", "jaimito", "jorgito"]. Si buscamos a Dewey, lo encontraremos en la posición 3 de disney_en. La posición 3 de disney_es nos devuelve el nombre que andábamos buscando: "jaimito"
.
Volviendo a la temática de SMS, deberemos convertir ciertas palabras a sus equivalencias en lenguaje SMS (muchas veces, una sola letra o símbolo). El código que realiza la conversión es realmente sencillo, resulta necesitar mucho más espacio el establecimiento de ambos arrays, como se ve en la solución al traductor a SMS en IDEOne.
def sms_from_str(s: str) -> str:
words = [
"igual",
"mas",
"menos",
"masa",
"adios",
"ademas",
"aca",
"bien",
"bueno",
"gracias",
"que",
"te",
"cuanto",
"nada",
"nos",
"vemos",
"despues",
"para",
"principio",
"que",
"qndo",
"saludos",
"siempre",
"estoy",
"tambien",
"por",
"pero",
"porque"
]
sms = [
"=",
"+",
"-",
"+a",
"a2",
"ad+",
"ak",
"bn",
"bno",
"grax",
"k",
"t",
"knto",
"nd",
"ns",
"vms",
"dsps",
"pa",
"ppio",
"q",
"qndo",
"salu2",
"100pre",
"stoi",
"tb",
"x",
"xo",
"xk"
]
toret = ""
ws = s.strip().lower().split()
for w in ws:
word_pos = list.index(words, w) if w in words else -1
if word_pos > -1:
toret += sms[word_pos]
else:
toret += w
...
toret += " "
...
return toret.strip()
...
print(sms_from_str("recuerda que te vas a por pan bien bueno"))
Colocaremos el texto solución en toret. La idea es buscar la palabra en el array words
. Si la encontramos, podemos buscar la posición en la que estaba dentro del array sms
y concatenarla a toret. En otro caso, concatenamos la misma palabra sin convertir.
Y en la siguiente entrega, la versión para objetos de eliminación de if's.
Posted on September 23, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.