Ir al contenido


Foto

Creear un programa que sume numeros de 30 cifras usando strings¿?


  • Por favor identifícate para responder
14 respuestas en este tema

#1 reethok

reethok

    Newbie

  • Miembros
  • Pip
  • 5 mensajes

Escrito 01 mayo 2011 - 02:06

Bueno... en el tutorial que estoy siguiendo para aprender Pascal me propusieron el siguiente ejercicio:

Ejercicio propuesto: Crea un programa que sume dos números "grandes", de 30 cifras. Esos números deberemos leerlos como "string" y sumarlos "letra a letra". Para ello, deberás crear una función "sumar", que reciba como parámetros dos "strings", y que devuelva su resultado en un nuevo "string".


Y la verdad... la única forma que se me ocurre para lograrlo es exageradamente larga (crear un array de bytes (del 1 al 30) en el que se guardará el valor de cada cifra del string... eso para el numero 1 y el numero 2 tambien... y para el resultado tambien (aquí más de 30...) y poner una condicion de que si la suma del primer byte de los string da más de 10... anote solo la ultima y la primera la sume con el siguiente byte... pero es demasiado tedioso...

A alguien se le ocurre una forma más sencilla?

Gracias!

  • 0

#2 Marcmiralles

Marcmiralles

    Advanced Member

  • Miembros
  • PipPipPip
  • 108 mensajes
  • LocationEspaña

Escrito 01 mayo 2011 - 09:46

Yo lo que haría es hacer un For / Next  que fuese recorriendo cada uno de los caracteres del string, de esa forma con tres o cuatro líneas de código lo tendrías resuelto.

Como también soy novato no recuerdo el Pascal cual es el comando para sacar un carácter de un string.

Busca cual es este comando, lo demás es pan comido

Suerte

Marc Miralles
  • 0

#3 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 01 mayo 2011 - 10:54

Hola reethok

¿ Puedes poner un ejemplo de como quieres que se sume letra por letra ? No me queda claro que es lo que quieres.

Salud OS
  • 0

#4 reethok

reethok

    Newbie

  • Miembros
  • Pip
  • 5 mensajes

Escrito 01 mayo 2011 - 03:13

Yo lo que haría es hacer un For / Next  que fuese recorriendo cada uno de los caracteres del string, de esa forma con tres o cuatro líneas de código lo tendrías resuelto.

Como también soy novato no recuerdo el Pascal cual es el comando para sacar un carácter de un string.

Busca cual es este comando, lo demás es pan comido

Suerte

Marc Miralles


Me podrías poner un ejemplo de como hacerlo, porfavor?

Hola reethok

¿ Puedes poner un ejemplo de como quieres que se sume letra por letra ? No me queda claro que es lo que quieres.

Salud OS


Supongamos que en el primer string escribo 83274 y en el segundo 38347... entonces sumaria string1[5] y string2[5] dando como resultado (7+4) = 11... que anote el ultimo digito (1) y el siguiente lo pase a sumar al siguiente digito: string1[4] + string2[4] + 1(que venía sobrendo) = (7+4+1) = 12... se anota el 2 y el 1 se pasa a sumar al siguiente digito y así sucesivamente...

  • 0

#5 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 01 mayo 2011 - 03:21

¿Necesariamente debe hacerse con strings?
Es que me parece algo absolutamente aparatoso, ya que nos condiciona a hacer conversiones entre cadenas (strings) y números:

Cadena -> Numéro -> Cadena

Yo lo encararía directamente como un array numérico. Es decir,



delphi
  1. Type
  2. TBigNumber30 = array[1..30] of integer;



De modo que las operaciones pueden hacerse con menos dificultad y lo más "pesado" ahora sería como mostrar dicho número en pantalla.



delphi
  1. var
  2. Nro1, Nro2, Nro3: TBigNumber30;



Por ejemplo, sumar la unidad:



delphi
  1. Nro3[30] = nro1[30] + Nro2[30];



Ahora bien, esto no es lo deseable, como se aprecia... cada posición es un integer y no nos sirve de nada. En realidad necesitamos llevar el acarreo hacia la siguiente cifra, y así hasta llegar al final. La pregunta aquí es ¿Cómo sacamos el acarreo?  Hay que repasar un poquito las clases de primaria 

Por empezar debemos hacer una corrección, en lugar de integer diseñemos un tipo especial:



delphi
  1. Type
  2. TDecimal = 0..9;
  3. TBigNumber30 = array[1..30] of TDecimal;



Volvamos al tema del acarreo, ¿Cuándo se da el caso? Cuando la suma de ambos dígitos es 9. Por ejemplo, 8 + 7 = 15. El acarreo es 1, que se debe sumar a la "siguiente" (a la posición anterior según el array) cifra. En la posición actual queda el 5.

Entonces para toda cifra debemos seguir esta lógica:



delphi
  1. Nro3[pos] := AcarreoPrevio + Nro1[pos] + Nro2[pos];



No todo está dicho, pero creo que con ello ya la deberías ir pillando.
Claramente se vé en el ejemplo anterior que necesita cierta correción. ¿Adivinas cual? 

Ahora bien, esto mismo se puede hacer con los strings. Sabiendo que un strings puede ser tratado como un vector, podemos ir recorriendo desde Length() hasta 1 haciendo las conversiones y operaciones necesarias.

Espero haberme explicado.

Saludos,
  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 01 mayo 2011 - 04:03

Supongamos que en el primer string escribo 83274 y en el segundo 38347... entonces sumaria string1[5] y string2[5] dando como resultado (7+4) = 11... que anote el ultimo digito (1) y el siguiente lo pase a sumar al siguiente digito: string1[4] + string2[4] + 1(que venía sobrendo) = (7+4+1) = 12... se anota el 2 y el 1 se pasa a sumar al siguiente digito y así sucesivamente...


Por lo que leo veo que entiendes la lógica, así que mi pregunta ahora es ¿Cuál es tu duda realmente? ¿En que tienes dificultades?

Saludos,
  • 0

#7 Marcmiralles

Marcmiralles

    Advanced Member

  • Miembros
  • PipPipPip
  • 108 mensajes
  • LocationEspaña

Escrito 01 mayo 2011 - 04:45


Yo lo que haría es hacer un For / Next  que fuese recorriendo cada uno de los caracteres del string, de esa forma con tres o cuatro líneas de código lo tendrías resuelto.

Como también soy novato no recuerdo el Pascal cual es el comando para sacar un carácter de un string.

Busca cual es este comando, lo demás es pan comido

Suerte

Marc Miralles


Me podrías poner un ejemplo de como hacerlo, porfavor?



Ahora es muy tarde para mi, mañana trato de ponerte el ejemplo, pero recuerda que soy novato.  *-)
  • 0

#8 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 02 mayo 2011 - 02:30

Una aproximación simple y creo que fácil de entender, puede ser esta:



delphi
  1. uses
  2.     StrUtils, Math;
  3.  
  4. function SumaEnteros(S1, S2: String): String;
  5. var
  6.   i, l, Carry: integer;
  7.   R: String;
  8. begin
  9.   Result:= '';
  10.   S1:= ReverseString(S1); S2:= ReverseString(S2);
  11.   l:= Max(Length(S1), Length(S2));
  12.   Carry:= 0;
  13.   for i:= 1 to l do
  14.   begin
  15.     if Length(S1) < l then S1:= S1 + '0';
  16.     if Length(S2) < l then S2:= S2 + '0';
  17.     R:= ReverseString(IntToStr(StrToInt(S1) + StrToInt(S2) + Carry));
  18.     if Length(R) > 1 then Carry:= 1 else Carry:= 0;
  19.     Result:= Result + R[1];
  20.   end;
  21.   if Carry <> 0 then Result:= Result + '1';
  22.   Result:= ReverseString(Result);
  23. end;



Uso ReverseString como truco para no tener que alinear las cifras que no tienen el mismo número de dígitos. La función asume que las dos cadenas contienen números enteros válidos, sin caracteres no numéricos, sin espacios ni caracteres de puntuación.


Saludos.
  • 0

#9 Marcmiralles

Marcmiralles

    Advanced Member

  • Miembros
  • PipPipPip
  • 108 mensajes
  • LocationEspaña

Escrito 02 mayo 2011 - 03:00


Me podrías poner un ejemplo de como hacerlo, porfavor?


Lo prometido es deuda, así que allá va. No le veo el sentido al ejercicio más allá de trabajar con cadenas y conversiones en plan antiguo como era repetir millones de veces qwerty para aprender a escribir a máquina, pero.....


delphi
  1. program project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}{$IFDEF UseCThreads}
  7.   cthreads,
  8.   {$ENDIF}{$ENDIF}
  9.   Classes,SysUtils
  10.  
  11.   { you can add units after this };
  12.  
  13. {$R *.res}
  14. var
  15.   c1,c2,r1,resultado,u1,u2:string;
  16.   v1,v2,count:byte;
  17.  
  18. begin
  19.   Write('entre un numero de 30 digitos: ');
  20.   Readln(u1);
  21.   Write('entre otro numero de 30 digitos: ');
  22.   Readln(u2);
  23.   For count :=1 to 30 do
  24.       begin
  25.         c1 := copy(u1,count,1);
  26.         c2 := copy(u2,count,1);
  27.         v1 := StrToInt(c1);
  28.         v2 := StrToInt(c2);
  29.         r1 := IntToStr(v1+v2);
  30.         resultado := resultado + r1
  31.       end;
  32.   writeln(resultado);
  33. end.                   



Seguro que habrá otras formas pero ésta es simple y funciona

Suerte.

Marc Miralles
  • 0

#10 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 02 mayo 2011 - 07:41

Hola

Solo una anotación, la suma debería de hacerse en un clico de 30 a 1 no de 1 a 30, esto porque es una suma de dos cantidades. Me parece que el asunto es ver el algoritmo que se sigue para la obtención del resultado, porque todo eso se evita haciendo una suma de dos funciones StrtoInt()

Salud OS

Edito:

Uso ReverseString como truco para no tener que alinear las cifras que no tienen el mismo número de dígitos.


No habia visto esto, tienes mucha razón amigo escafandra. (y)
  • 0

#11 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 02 mayo 2011 - 09:37

Hola muchachos,
Pues que quieren que les diga... me sigue pareciendo más que lioso tener que estar haciendo esas operaciones con cadenas junto con conversiones.

Si manejarlo como strings es un requisito, y si se puede aceptar que el string SIEMPRE será de 30 (de ser necesario anteponiendo ceros a la izquierda) entonces no veo porqué no hacer un FOR desde 30 hasta 1 y leer dígito a dígito, calculando sumas y acarreos.



delphi
  1. for pos := 30 to 1 do
  2. begin
  3. n1 := StrToInt(nro1[pos]); // Obtener dígito pos-ésimo del nro1
  4. n2 := StrToInt(nro2[pos]); // Obtener dígito pos-ésimo del nro2
  5. // aquí se opera
  6. n3 := // operación de suma estilo "primaria o de escuela".
  7. nro3[pos] := n3;
  8. end;



Y el procedimiento para ello sería casi análogo a mi propuesta con el vector.
La intención de mi mensaje no era dar la solución tan abiertamente, pero aportar una luz a reethok.

Saludos,
  • 0

#12 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 02 mayo 2011 - 09:56

Claro, egostar. El ejemplo que propongo es un poco mas general y suma cifras de n dígitos sean 30 o mas. Para poder sumar números de distinta longitud he usado el truco de invertir las cadenas y evitar el engorroso alineamiento de las mismas si se empieza desde el final, así, el algoritmo es independiente de la longitud de las mismas.

Como dice Delphius es engorroso tratar con String, pero si el ejercicio así lo pide, pues así sea. POr otro lado me parece un buen ejercicio aunque no sea la forma mas eficaz de trabajar. Las conversiones pueden simplificarse si restamos/sumamos el carácter '0' en lugar de usar StrToString/IntToStr. Preferí no hacerlo así para que el código sea mas legible.

Veo un error en el código de Marcmiralles en la gestión del acarreo.

reethok es el mejor sabe lo que tiene que realizar según el trabajo pedido.


Saludos.

  • 0

#13 Marcmiralles

Marcmiralles

    Advanced Member

  • Miembros
  • PipPipPip
  • 108 mensajes
  • LocationEspaña

Escrito 02 mayo 2011 - 03:56



Veo un error en el código de Marcmiralles en la gestión del acarreo.


Saludos.[/size][/color]


leñe, Escafandra ¿puedes explicarte?, que soy novatillo yo también y me interesa saber donde la 'cagué', jeje.
  • 0

#14 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 02 mayo 2011 - 05:11


Veo un error en el código de Marcmiralles en la gestión del acarreo.

Saludos.

...Escafandra ¿puedes explicarte?...


Bueno, simplemente no llevas el acarreo, lo dejas automático para la suma de un par de dígitos, pero no lo arrastras. Suma con tu programa 99 + 1, el resultado te dará 910. Añades simplemente la suma de 9+1 al String, sin considerar que "te llevas 1" y sólo debes añadir un '0'.



delphi
  1. ..............................
  2.         r1 := IntToStr(v1+v2);
  3.         resultado := resultado + r1
  4. ..............................




Saludos.
  • 0

#15 jorgeu

jorgeu

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 179 mensajes
  • LocationMaracaibo

Escrito 03 mayo 2011 - 09:11

A nivel profesional buscaría usar algo como esto:


http://gmplib.org/
  • 0




IP.Board spam blocked by CleanTalk.