|
Con éste escueto título pretendemos presentar un algoritmo tal que dada una cantidad numérica entera y positiva sea capaz de expresarla con texto, es decir, tal y como la leemos.
Este tipo de algoritmos se utiliza, por ejemplo, en la emisión de cheques bancarios y otros documentos en los que se escriben cifras como método adicional para evitar errores y/o falsificaciones. También se utilizan en aplicaciones de síntesis de voz, en los cuales puede ser necesario "leer" las cifras.
En principio, no es un algoritmo complicado, ya que el sistema que utilizamos para leer las cifras está basado en dar nombre a las unidades, decenas y centenas (con lo que podemos leer los nombres de cualquier números de tres cifras) y a partir de ahí utilizar agrupaciones de tres en tres (miles) y de seis en seis (millones, billones, etc...). Es decir, podemos encontrar una estructura regular en la forma de leer los números.
Sin embargo, hacerlo relativamente bien en español no es tan sencillo (comparado con idiomas como el inglés, por ejemplo), ya que por un lado se utiliza una enorme cantidad de irregularidades (por ejemplo, números con nombre propio, como el doce, que si tuviera un nombre regular debería llamarse diez y dos" y de estos tenemos un montón -del once al veintinueve-) y por otro lado, el hecho de que en español los números pueden actuar tanto de pronombre como de determinante, y en éste último caso, tanto femenino como masculino (Ejemplo: 761 puede actuar como pronombre: "Setecientos sesenta y uno", como determinante masculino: "Setecientos sesenta y un euros", o femenino: "Setecientas sesenta y una libras esterlinas").
Vamos a ahondar un poco más en el tema y a descubrir los problemas a los que nos enfrentamos.
Empecemos por el hecho de que una cantidad escrita puede actuar como pronombre, o como determinante. (Aquí me han ayudado. Gracias kitty ;-).
- Los determinantes son una clase de palabras muy heterogéneas, pero en general, y simplificando mucho, podríamos decir que acompañan siempre a un nombre, a un sustantivo, haciendo más preciso su significado. En español, cuando los números actúan de determinante tienen género, el mismo del sustantivo al que acompañan. Quizá el determinante más sencillo de este tipo sea el del número 1: Ejemplos: Una jirafa, un león.
Pero lo mismo ocurre si el número es otro:
- Doscientas veintiuna jirafas
- Doscientos veintiún leones
- Los pronombres son palabras -al igual que antes, simplificando mucho- que pueden tomar el papel de un sustativo. En el caso de los números, representan al propio nombre del número.
Por ejemplo:
- ¿En qué año nació el pianista Chick Corea
? (Me gusta mucho ;-): En mil novecientos cuarenta y uno (Fíjate: ni "cuarenta y un" ni "cuarenta y una")
- ¿Qué número ha salido premiado en la lotería de ayer?: El treinta y seis mil setecientos ochenta y uno.
El segundo tema son las irregularidades. (Nota: al hablar de la primera, segunda, tercera... cifras de un número empezamos a contar por la derecha, la menos significativa, la unidad. Es decir, la primera es la unidad, la segunda la decena... etc.)
- Las cifras básicas (unidades) tienen nombre: uno, dos, tres... hasta el nueve. Las decenas también: diez, veinte, treinta... hasta el noventa. La regla general dice que un número de dos cifras se forma con el nombre de la decena, la conjunción "y" y el nombre de la unidad. Por ejemplo, el 38: "treinta y ocho", pero esto no es cierto para los números 11 a 19 y 21 a 29, que tienen nombre propio: once, doce, trece, catorce, quince.... y veintiuno, veintidós, veintitrés... hasta el veintinueve. Pero no sólo eso, en los que terminan en 1, la expresión del número cambia según actúen de determinante masculino, femenino o pronombre. Ejemplo: veintiún, veintiuna, veintiuno. También hay que poner ojo a las tildes: un, dos y tres no llevan tilde, y tampoco "treinta y un", "treinta y dos" y "treinta y tres", pero sí llevan "veintiún", "veintidós" y "veintitrés".
- Las centenas también tienen nombre propio: cien, doscientos, trescientos, cuatrocientos... pero también cambian cuando el número actua de determinante femenino por un lado (ej: trescientas) o de determinante masculino o pronombre por otro (trescientos). El cien es otra excepción... cuando la cifra es exactamete 100 se llama "cien", y si no es así "ciento".
- A partir de la cuarta cifra hasta la sexta se repite el mismo esquema que de la 1ª a la 3ª. Basta con agregar la partícula "mil"... pero también hay irregularidades. Aquí ya no importa si el número actúa como pronombre. Las cifras 4ª a 6ª forman en sí mismas un número que es determinante del "mil". Pero ese "mil" se interpreta como masculino si toda la cifra está actuando como pronombre o determinante masculino, y como femenino si toda la cifra está actuando como determinante femenino. Ej: 721000: Setecientas veintiuna mil (det. femenino) o 721000: Setecientos veintiún mil (determinante masculino o pronombre).
- Hay otra excepción más relacionada con las cifras 4ª a 6ª: si la cantidad que representan es exactamente 1, no se menciona, y sólo se pone la partícula "mil", en lugar de "un mil". Ej: 1200 pesetas: mil doscientas pesetas (en lugar de una mil doscentas pesetas). 101200: ciento una mil doscientas pesetas.
- A partir de la 7ª cifra y hasta la 12ª podemos repetir el mismo proceso que hacemos con las cifras 1ª a 6ª. De hecho, este esquema se vuelve a repetir cada 6 cifras (de la 13ª a la 18ª, de la 19ª a la 24ª...) Ya sabemos que las cifras 7ª a 12ª representan millones... Pero:
- Esas cifras actúan como determinante de los millones (y no de todo el número), y por lo tanto, tienen género másculino.
- Los millones tienen número: singular cuando es exactamente un millón, y plural cuando son dos o más millones.
- Las siguientes agrupaciones de seis cifras determinan a los billones (cifras 13ª a 18ª), trillones (cifras 19ª a 24ª) y cuatrillones (25ª a 30ª) con ls mismas reglas que para los millones. Más allá de eso, no se suelen leer las cifras.
Por último, una puntualización. En el mundo de habla inglesa, la palabra "billion" equivale a los "mil millones" en español, y la palabra "trillion" equivale al "billón" en español... (también ocurre algo similar en ruso, griego y brasileño). Es lo que llaman la "escala corta", en la que los grupos de cifras más grandes se hacen de tres en tres en lugar de de seis en seis (la "escala larga" que se utiliza en español y el resto de idiomas). Hay voces que dicen que eso provoca confusión, y han propuesto la utilización en español de extraños palabros como "millardo " y la escala corta de numeración también en español. Por supuesto que sería fantástico que todos los paises de mundo utilizaramos una forma similar de nombrar a los números... pero de momento no la hay.... cada lengua tiene su propia forma de leer los números basada en la escala corta o en la larga... pero un número es siempre el mismo número, se lea en un idioma o en otro. Las confusiones que yo he notado siempre han sido por parte de medios de comunicación en los que algún zoquete que no sabe ni inglés ni español ni conoce las culturas de las cuales está traduciendo ha traducido una cifra de cualquier manera... así que personalmente me parece absolutamente prescindible cualquier otro matiz al respecto... las cifras en unos idiomas se leen de una manera, y en otros de otra. En español, y mientras ninguna voz absolutamente autorizada (ja!) diga lo contrario, utilizamos la escala larga.
Pero vamos con el algoritmo. En esta ocasión, vamos a construir una clase en C#, a la que le vamos a colocar un método estático public static String Convierte(String s, Tipo t), siendo Tipo un enumerado de tres elementos: public enum Tipo {Pronombre, DetMasculino, DetFemenino};
Al método Convierte le pasaremos una cadena de hasta 30 carácteres, que contendrá la representación de un número con cifras de "0" a "9", sin puntos ni comas ni espacios ni ningún otro símbolo. Éste método devolverá la representación del número escrito, y dependiendo del segundo parámetro, como determinante masculino o femenino, o como pronombre.
Para ello, vamos a apoyarnos en una serie de métodos privados.
- El método private static bool EsNumero(String s) simplemente nos dirá si la cadena s está formada exclusivamente por carácteres del "0" al "9".
- El método private static String ConvierteTodo(int i, Tipo t) tomará la cadena y la irá descomponiendo de seis en seis cifras, empezando por las menos significativas, y se las irá pasando al método Convierte6. Éste devolverá el texto correspondiente a esas seis cifras, y de vuelta en ConvierteTodo, se añadirán las particulas correspondientes a millones, billones, trillones y cuatrillones. Se tiene en cuenta que las primeras seis cifras menos significativas actúan como indica la variable "Tipo t", y que los siguientes grupos de seis son determinantes masculinos de "millones", "billones", etc. Se tiene también en cuenta el número (millón vs. millones).
- El método private static String Convierte6(int i, Tipo t) se encargará de devolver el nombre correspondiente a un grupo de seis cifras, teniendo en cuenta cómo actúa este grupo, según el parámetro t. El proceso consiste en descomponer el grupo de seis en dos partes de tres cifras, y pasar cada parte al método Convierte3. Entre las dos partes que devuelva Convierte3 se insertará la partícula "mil" teniendo en cuenta las irregularidades comentadas.
- El método private static String Convierte3(int i, Tipo t) se encargará de devolver el nombre correspondiente a un grupo de tres cifras (centenas-decenas-unidades). Se encarga de las irregularidades de las centenas y se apoya en el método Convierte2 para las decenas y las unidades.
- El método private static String Convierte2(int i, Tipo t) toma un grupo de dos cifras y devuelve su nombre escrito, teniendo en cuenta los nombres propios de los números 10 a 29. Se apoya en Convierte1.
- Por último, el método private static String Convierte1(int i, Tipo t) simplemente toma un número de una cifra y lo devuelve escrito.
Poco más... el resto es puramente trivial. Aquí tienes la clase entera, úsala como quieras.
Puedes descargar el código en C#, y si quieres una versión en Java, también. La versión en Java es prácticamente una traducción directa de la de C# (ojo al método substring de la clase string, que cambia de C# a Java).
Si quieres ver el código en acción, aquí tienes una mini-demo.
|