cdu = ( unidad, decena, centena ).
Number = Cadena de entrada ( contiene el numero que se va a leer )
l = longitud de la cadena de entrada
i = posicion de cada digito comenzando desde la ultima posicion. vi: l
d = digito ( cada uno de los digitos que se leen de la entrada ).
u = undad. vi : u = 1 u = u * 10, ( unidad = 1, decena = 10 centena = 100 )
v = vector ( almacena las cadenas de lectura ). Unidad: V[ n ] Decena: V[ 20 + p ] exceptuando [ 10 - 19 ] = V[ n ] Centena: V[ 30 + p ] Miles/millones/billones = V[ 40 + p ]
n = valor acumulativo cdu. vi : n = 0 n = d * u + n
s = buffer auxiliar ( almacena la concatenacion de cdu ). s = c + d + u
z = buffer principal. ( contiene la cadena completa de salida ). z = cdu + cdu + cdu ...
p = posicion ( calcula la posicion en el vector de cadenas de lectura ) vi: p = 0 decena: p = d - 2 centena: p = d - 1 Miles/Millones: p = { miles = 0, millones = 1, billones = 2 }
t = cadena temporal.
j = contador de milesimas/millones/billones. vi: 0 Ejs: 123.873.984.930 : j = 3, 1.983 : j = 1
r = diferencia entre la longitud y la posicion del digito. r = l - i
----------------------------------------------------------------------------------------------------------------------
La lógica del algoritmo es empezar leyendo carácter a carácter de derecha a izquierda (cadena inversa), cada 3 dígitos almacenamos el buffer auxiliar en el buffer principal, luego reiniciamos el buffer auxiliar y las operaciones (se reinicia todo excepto el buffer principal y contador de miles/millones/billones).
U: valor de la unidad, inicia
en 1, U = U *
10 , { U = 1 = Unidad, U =10=Decena, U=100=Centena}
Reiniciamos por cada 3 dígitos que se
lean (CDU = Centena.Decena. Unidad)
Ej:
leemos 7254
it
1: U = 1
it
2: U = 10
it
3: U = 100
Reiniciamos U = 1
it
4: U = 1
….
n:
valor acumulativo,
inicia en 0, n = d * u + n
Reiniciamos n = 0 por cada 3 dígitos que se lean (CDU)
Ej:
leemos 7254
it
1: [ d = 4, U = 1, n = 0 ] entonces
n = ( 4 * 1 + 0 ) = 4
it
2: [ d = 5, U = 10, n = 4 ] entonces
n = (5 * 10 + 4) = 54
it
3: [ d = 2, U = 100, n = 54 ] entonces
n =( 2 * 100 + 54 ) =
254
Reiniciamos n = 0
it
4: [ d = 7, U = 1, n = 0 ] entonces
n =( 7 * 1 + 0 ) = 7
…
Tomemos los valores de n y u de
arriba para cada iteración.
Unidades: posiciones en el vector [0
– 9] entonces se accede de forma directa
V[n]
Ej:
leemos 7254
it
1: [ d = 4, U = 1, n = 4 ] , V[4] = “cuatro”
it
2: …entra en decena
it
3: …entra en centena
Reiniciamos n = 0, U = 1
it
4: [ d = 7, U = 1, n = 7 ], V[7] = “siete”
…
Decenas: posiciones en el vector [20 – 27], entonces V [20 + p],
donde p = d – 2, si p < 0 entonces está
en el rango [10
- 19] su valor se obtiene con V[n]
Ej:
leemos 7254
it
1: …entra en unidad
it
2: [ d = 5, U = 10, n = 54 ] entonces, p = ( 5 - 2)
= 3, V[23] = “cincuenta”,
Si el digito leído fuera 1 en lugar de
5, es decir fuera 7214, entonces n = 14, p = (1 - 2) = (-1) < 0, por tanto obtendríamos su valor directo con V
[14] =”catorce” limpiaríamos el valor de la unidad que era “cuatro”.
it
3: …entra en centena
Reiniciamos n = 0, U = 1
it
4: …entra en unidad
…
Centenas: posiciones en el vector [30 – 38], entonces V [30 + p],
donde p = d – 1
Ej:
leemos 7254
it
1: …entra en unidad
it
2: …entra en decena
it
3: [ d = 2, U = 100, n = 254 ], p = (2 - 1) = 1, V[31] = “doscientos”
Reiniciamos n = 0, U = 1
it
4: …entra en unidad
Miles/millones/billones: V [40 + p], donde p = {0, 1 o 2}, si ( j > 2 ) entonces p = 2 sino p = j &
1, r = l - i
( J & 1
) devuelve 0 si j es par y 1 si es impar, ( 0 & 1) = 0,
(1 & 1) = 1, (2 & 1) = 0, (3 & 1) = 0 …
r es la
diferencia entre l (longitud total de la cadena numérica de entrada ) e i( índice del digito leído )
j es un
valor que inicia en 0 y se incrementa siempre que encuentre una unidad
Miles/millones/billones
Solo se
calcula Miles/millones/billones si r >
0, verifica que hayan dígitos por leer y si r mod
3 = 0, es decir si se ha leído una (CDU),
entonces si ambas condiciones se cumplen calculamos p y
buscamos en el vector.
Ej:
leemos 7254
it
1: [ j = 0, l = 4, i
= 4 ] …entra en unidad r = ( 4 – 4 ) = 0, verificamos ( 0 >
0 ) No, ( 0 mod 3 = 0 ) Si
it
2: [ j = 0, l = 4, i
= 3 ] …entra en decena r = ( 4 – 3 ) = 1,
verificamos ( 1 > 0 ) Si, ( 1 mod 3 = 0 )
No
it
3: [ j = 0, l = 4, i
= 2] …entra en centena r = ( 4 – 2 ) = 2,
verificamos ( 2 > 0 ) Si, ( 2 mod 3 = 0 )
No
Reiniciamos n = 0, U = 1
it
4: [ j = 0, l = 4, i
= 1] …entra en unidad r = ( 4 – 1 ) = 3, verificamos ( 3 >
0 ) Si, ( 3 mod 3 = 0 ) Si
Se
cumplen ambas condiciones
entonces calculamos p, si ( j = 0) >
2 No entonces p = ( 0 & 1 ) = 0,
V[40
+ 0 ] = “mil”
Ej: para 2258, l = 4, entonces, iteración 1: [i = 4, d = 8, u = 1, n = 0], n = ( 8 * 1 + 0 ) = 8 , si u = 1, entonces accedemos a su valor en el vector directamente v [ n ], el valor será s = v[ 8 ] = "ocho", entonces n = 8, u = 10, s ="ocho", iteración 2: [i = 3, d = 5, u = 10, n = 8], n = ( 5 * 10 + 8 ) = 58, si u = 10, entonces p = d – 2 es decir p = ( 5 – 2 ) = 3, si p >= 0 y d <> 2 entonces t = v[ 20 + p ] , t = V[ 23 ] = “cincuenta”, entonces n = 58, u = 100, s = ( t + “ y ” + s ) = “cincuenta y ocho”, si d = 2 si en el ejemplo fuera 1228 entonces seria , n = ( 2 * 10 + 8 ) = 28, p = ( 2 – 2 ) = 0, t = v[ 20 ] = “veinte”, s = ( “veinti” + s ) = “veintiocho” para esta iteración, si p < 0 quiere decir que la unidad de decena esta entre [ 10 – 19 ] por lo cual accedemos directamente v[ n ] , si en el ejemplo fuera 1218 entonces en esta iteración el valor acumulativo seria n = ( 1 * 10 + 8 ) = 18 , p = ( 1 – 2 ) = (-1), por tanto obtendríamos t = v[ 18 ] = “dieciocho”, iteración 3: [i = 2, d = 2, u = 100, n = 58], n = ( 2 * 100 + 58 ) = 258, si u = 100, entonces p = d – 1 es decir p = ( 2 – 1 ) = 1, si d <> 1, entonces t = v[ 30 + p ] , t = v[ 31 ] = “doscientos”, s = ( t + “ “ + s ) = “doscientos cincuenta y ocho”, si d = 1 si en el ejemplo fuera 1128 entonces seria entonces p = ( 1 – 1 ) = 0, t = v[ 30 + p ] + “to”, t = ( v[30] + “to” ) =”ciento”, s = ( t + s ) = “ciento cincuenta y ocho”, como u = 100 entonces reiniciamos todas las variables pero antes guardamos en el buffer principal (z) el buffer auxiliar = cdu (s), es decir z = s = “ciento cincuenta y ocho”, reiniciamos variables u = 1, s = ””, n = 0, repetimos los pasos anteriores iteración 4: [i = 1, d = 2, u = 1, n = 0] , aquí hacemos lo mismo que en la iteración 1, n = ( 2 * 1 + 0 ) = 2 , si u = 1, si u = 1, entonces accedemos a su valor en el vector directamente v [ n ], el valor será s = v[ 2 ] = "dos", como hemos terminado de leer los caracteres terminamos las iteraciones.Este paso se hace en cada iteración, verifica los miles/millones/billones
j
es un contador miles/millones/billones que
inicia en 0 e incrementa siempre que
encuentra una unidad de miles/millones/billones.
l
es longitud de vector
i
es el índice de posiciones de cada digito
1.
obtener
la posición real, r = l – i
2.
Verificar
si hay más números por leer esto se verifica, r > 0
3.
verificar
si es es miles/millones/billones, r mod 3 = 0
4.
si
2 y 3 se cumplen, calcular posición del vector, entonces
p = ( r
> 10 ) ? 2 : j++ & 1;
explico esta instrucción:
si r >
10, p = 2 es decir que son billones, si no es asi hago un and a nivel de bits sobre j, este and (& ) lo
que me devuelve es 0 si es par y 1 si es impar, Ej:
p = j & 1
para j =
0 : p = ( 0 & 1 ) = 0 , j = 1 : p= (1
& 1) = 1 , j =2 : p ( 2 & 1 ) = 0 …
5.
t
= V[ 40 + p ]
para
el ejemplo actual 2258, solo se
cumplen las 2 condiciones en la
iteracion 4: como i empieza en l, entonces parar it 1: i = 4, it 2: i
= 3, it 3: i = 2, it
4: i = 1
iteracion 4: [l
= 4, i = 0, j = 0, r = l – i ], entonces r = ( 4
- 1 ) = 3,
r
> 0 = si , r mod 3 = 0 = si, se cumplen ambas entonces, r > 10 no cumple por tanto p = j++ &
1, p = ( 0 & 1 ) = 0 ,
incrementa j = 1, accedemos a vector t =
v[40 + p], t = v[40] = “mil”, z = ( “ ” + t + “ ” + z ) = “ mil doscientos cincuenta y ocho”
Z = ( s + z ) , como z = “ mil doscientos cincuenta y ocho” y s = “dos”, entonces z = “dos mil doscientos cincuenta y ocho”