duda de algorismos... ¬___________¬

wenas gente, tengo una duda con unos ejercicios ue me estan volviendo loco XD El caso es:

Como haríais un algorismo que invirtiera los dígitos de un número. Por ejemplo que 123 quedará 321, 4 quedará 4, 44545 quedara 54544, etc?

La otra es:

Como hariais un algorismo que con dos numeros enteros no negativos muestre por pantalla si X es sufijio de Y o a la inversa. Por ejemplo, 78 es sufijo de 278, 6 es sufijo de 26, etc...

Para este hemos hecho un algorismo (está en catalán pero supongo que se entiende), pero es muy chapucero porque tienes que introducir el numero con un punto al final.... (lol) y solo permite hacerlo con números de tres cifras (adem´ñas de que desconocemos totalmente si está bien o no :S)


/* Cal introduir el número "x" i "y" en el format següent: */

/* Per a x=20 hem de posar x=20.00 */

/* Per a y=25 hem de posar y=25.00 */

/* Aquest algorisme té limitacions: */

/* - Només es poden tractar valors de 3 xífres com a màxim */

algoritme Mostrar_Sufix

*

var
x = enter
y = enter
num_char = enter
posicio = enter
posicio2 = enter
ax = enter
bx = enter
cx = enter
ay = enter
by = enter
cy = enter

fivar


inici
Llegir(car) /*comencem a comptar el número de carácters */

num_char <-- 1


mentre ¬(x='.') V ¬(y='.')
num_char+1

fimentre si (x='.') V (y='.') aleshores


posició <-- (num_char - (num_char - 1))

fisi


posicio2 <-- posicio /* copiem les variables per tal de tracter x i y per separat en el següent punt */

mentre ¬(x='.') /* Copiem el valors de cada caràcter de la xifra a una variable */


ax <-- Llegir(car)
posicio + 1


bx <-- Llegir(car)
posicio + 1


cx <-- Llegir(car)
fimentres


mentre ¬(y='.')


ay <-- Llegir(car)
posicio2 + 1


by <-- Llegir(car)
posicio2 + 1


cy <-- Llegir(car)

fimentres /* Donem els resultats */


si ax=ay V bx=by V cx=cy V x>y aleshores
Escriure( Y es sufix de X)

si_no
Escriure(Y no es sufix de X)

fisi


si ax=ay V bx=by V cx=cy V x Escriure( X es sufix de Y)

si_no
Escriure(X no es sufix de Y)

fisi

fi



Sí, soy consciente de la chapuza v_v, se agradece cualquier ayuda [beer]
El primero es simplemente hacer un bucle for que tenga como límite el tamaño de la cadena de caracteres que contiene al número, una vez hecho, creas otra cadena de caracteres de la misma longitud y el bucle lo que haría sería meter el elemento 1 de la cadena original en el elemento n de la cadena final, incrementar el índice y continuar.

Para el otro, yo lo haría usando recursividad. Comparas la longitud de los dos números, al de mayor longitud lo llamas a, al otro b. Empiezo con i=1. Si cifra i-esima de b coincide con cifra i-esima de a, llamo de nuevo al algoritmo incrementando el índice. En el momento que no coincidan, me salgo y devuelvo un booleano false por ejemplo. Si i llega a ser igual a la longitud de b, entonces es prefijo.

Son ejercicios sencillitos, no te compliques.
(Editado) Antes que nada, pregunta al usuario el valor de 'x' y asigna 0 a 'y'.
Yo haría un bucle "mientras 'x' sea mayor que 0", con este contenido:
A 'y' se la multiplica por 10 y se la asigna a sí misma
A 'y' se le asigna 'x' mod 10
'x' se divide entre 10 y se asigna a sí misma
Fin del bucle y del programa (bueno, puedes enviar el resultado a pantalla :P)


PD: Puedes usar enteros, no?


Editado otra vez: Joder, estoy dormido... no vi el segundo problema xD
Ahora lo miro y edito again.
el de los sufijos yo lo haria de la siguiente forma (a modo de funcion)

while ((x>0) && (y>0)) {

if ((x mod 10) != (y mod 10))
return false
else {
x = x/10
y = y/10
} //else
} // while
return true

PD: como puedo ponerlo para que me salga el texto anidado?
Bueno, en mi solución he hablado de cadenas de caracteres porque no se pedía otra cosa, y si vas a tomar una entrada por teclado, era lo que me parecía más natural. Pero no tiene mucha más historia si quieres tomar un integer directamente :P
yauros escribió:el de los sufijos yo lo haria de la siguiente forma (a modo de funcion)

while ((x>0) && (y>0)) {

     if ((x mod 10) != (y mod 10))
          return false
     else {
              x = x/10
              y = y/10
      } //else
} // while
return true


PD: como puedo ponerlo para que me salga el texto anidado?
Usando el editor avanzado: Estilos - Código.

PD: Esos dos return... no sería más majo una booleana?
me duele la cabeza tanto que ya no pillo nada xD llevo desde ayer con estos dos y algunos más, y lo peor de todo es que hay que irlo poniendo en una web que tiene un editor que pffff... xDD :S (dios mío, como puede existir un editor tan bueno (EOL) y otros tan malos??? dichosa web xD)

Det, de tu primera respuesta lo pillo hasta aquí:

Para el otro, yo lo haría usando recursividad. Comparas la longitud de los dos números, al de mayor longitud lo llamas a, al otro b. Empiezo con i=1. Si cifra i-esima de b coincide con cifra i-esima de a, llamo de nuevo al algoritmo incrementando el índice. En el momento que no coincidan, me salgo y devuelvo un booleano false por ejemplo. Si i llega a ser igual a la longitud de b, entonces es prefijo.

que ya me pierdo, puedes explicalo de algún modo más sencillo? :-P

yauros, tú ejemplo es usando funciones que (en teoria) aun no podemos usar. Tiene que ser algo a un nivel más sencillo

RubenGM, tu método consistiría en ir multiplicando y dividiendo cada número x 10 (x100, x1000, etc) hasta que cada número estubiera en su casilla correcta (invertida), no?

merci por las respuestas
RubénGM escribió:Usando el editor avanzado: Estilos - Código.
PD: Esos dos return... no sería más majo una booleana?


gracias. las normas de estilos van en contra de poner return en mitad del codigo, pero al final te acostumbras a ponerlos por todos lados jeje (aunque de todas formas en un codigo tan sencillo no dificulta la lectura)

bpSz escribió:yauros, tú ejemplo es usando funciones que (en teoria) aun no podemos usar. Tiene que ser algo a un nivel más sencillo


sin funciones es exactamente igual, tan solo en vez de devolver true, indica de alguna forma por pantalla o como indique el ejercicio que un numero es sufijo del otro
El segundo ejemplo yo te decía empleando el concepto de recursividad, que básicamente consiste en estructurar el programa así:

funcion(N) -> dentro de dicha función, voy a hacer ciertos cálculos, y al final, llamaré otra vez a la propia funcion, pero con un argumento más sencillo, por ejemplo funcion(N-1). Un ejemplo sería, cómo calculo los primeros 100 nºs primos? Hago una función primo(100), que devuelve todos los primos hasta 100. Dentro de esa función, cojo el argumento (100) y divido entre todos los números comprendidos entre 2 y 100-1. Si el resultado de todas las divisiones es inexacto, devuelvo el 100 por pantalla y hago primo(99). Si el resultado de alguna división es exacto, el número no es primo, por tanto simplemente hago primo(99) sin pintar nada por pantalla.

Es un ejemplo muy burdo, pero creo que se ve bien.

De todas formas, se puede hacer de una forma más sencilla sin usar recursividad, lo planteé usándola porque es más elegante. Yauros lo ha hecho de una forma muy fácil, simplemente vas comparando cada una de las cifras (por eso vas dividiendo entre 10), mientras sean iguales significa que puede ser prefijo. Si en algún momento dejan de ser iguales, no pueden ser prefijo, por lo que devuelves false y terminas el programa.
bpSz escribió:RubenGM, tu método consistiría en ir multiplicando y dividiendo cada número x 10 (x100, x1000, etc) hasta que cada número estubiera en su casilla correcta (invertida), no?

merci por las respuestas
Sí, más o menos... mod lo que hace es devolver el "residuo" de una división (viene a ser lo primero que me enseñaron en pseudocódigo, prácticamente o.O)

123 mod 10 = 3
123 mod 100 = 23
5 mod 2 = 1
5 mod 3 = 2
5 mod 4 = 1

etc :P



Si le entras el 5123 pasará algo así:

5123 % 10 = 3
0 * 10 + 3 = 3
5123 / 10 = 512

512 % 10 = 2
3 * 10 + 2 = 32
512 / 10 = 51

51 % 10 = 1
32 * 10 + 1 = 321
51 / 10 = 5

5 % 10 = 5
321 * 10 + 5 = 3215
5 / 10 = 0

Y ale, resuelto.

PD: Mod se escribe '%' en C# :P
yauros escribió: sin funciones es exactamente igual, tan solo en vez de devolver true, indica de alguna forma por pantalla o como indique el ejercicio que un numero es sufijo del otro


yauros, la ostia tienes razón, ¡qué pajaro qué estoy! XD es que estaba pensando ahora en otra cosa y tienes toda la razón con tu código. De todos modos hay una parte (la del final) que no pillo.

Porque es cierto si

x = x/10
y = y/10

????

No tendría que ser que ((x div 10) = y), o ((y * 10)= x) si (x>y) /\ ((x mod 10) = (y mod 10))?

EDITO:

Det, captado. Es que aún no hemos empezado con algorismos recursivos jeje

RubenGM, ok merci por la aclaración.

Esto es lo que pasa cuando el profesor cuelga en pdf los apuntes y te tienes que buscar la vida para entenderlos. Llegas a clase y el notas pasa cuatro diapositivas con cuatro textos y no te cuenta na de utilidad XD ¬_¬' (de lo peor que me ha tocado en profesores xD)


EDITO, me ha quedado algo así incluyendo lo que yo le decía a yauros:


var

x=enter
y=enter

fivar

inici

mentres ((x>0) /\ (y>0))

si ((x mod 10) != (y mod 10)) aleshores

Escriure(X no es sufixe de y)

fisi

si ((x mod 10) = (y mod 10)) /\ (x>y) /\ (y*10= x) aleshores

Escriure(X es sufixe de y)

fisi

fimentres

fi

¿Dónde estás estudiando, por curiosidad? :P
RubénGM escribió:¿Dónde estás estudiando, por curiosidad? :P


UAB (Autónoma de Barcelona) :-P (Al lado de la facultad de empresariales estamos. Supongo que nos lo ponen así para que conozcamos a alguna pija de empresariales y no tengamos que currar de informáticos, que dicen que está muy mal XD)


EDITO:

wenas, con el metodo de RubenGM, tengo un problema, os pego el pseudocódigo:

algorisme Invertir_Numero

var

x = enter
posicio = enter

fivar

inici

posicio <- 1

Llegir(posició)

mentres (x>0)

si (x>0) aleshores a<- x mod 10

fisi

posicio = posicio + 1

si (x>0) aleshores b<- x mod 100

fisi

posicio = posicio + 1

si (x>0) aleshores c<- x mod 1000

fisi

posicio = posicio + 1

si (x>0) aleshores d<- x mod 10000

fisi

fimentres

Escriure(a*1000+b*100+c*10+d*1)

fi


El problema es que no se me ocurre como hacer parar el bucle en determinado numero de caracteres.. porque tal y como lo tengo solo puedo invertir números de hasta 5 cífras... :S si quisiera invertir cualquier cantidad, como podría hacerlo?
bpSz, el codigo que te puse antes esta bien.......salvo por un "pequeño detalle", si uno de los numeros es cero y el otro uno distinto que no acabe en cero, falla. pero vamos es facil de arreglar.


lo de invertir el numero lo haria asi

// num es el numero que quieres invertir
// res el num invertido
x = num
mult = 1

while (x DIV 10!=0)
       mult = mult * 10
       x = x DIV 10

res = 0
while (num!=0)
     res = res + mult*(num MOD 10)
     mult = mult DIV 10
     num = num DIV 10

bpSz escribió:wenas, con el metodo de RubenGM, tengo un problema, os pego el pseudocódigo:



El problema es que no se me ocurre como hacer parar el bucle en determinado numero de caracteres.. porque tal y como lo tengo solo puedo invertir números de hasta 5 cífras... :S si quisiera invertir cualquier cantidad, como podría hacerlo?
A base de 'if's no puedes solucionarlo, necesitas un bucle (while/mientras).
todos esos ejercicios se pueden hacer de muchos modos.

Por ejemplo, para el de invertir, puedes obtener muchas soluciones diferentes con solo pasar a caracteres los enteros (por ejemplo una vez tengamos la cadena, obtener su longitud e invertirla con un bucle for o un while || utilizando vectores || ...) .

Que tiempos aquellos en los que curse 1º... [risita]
Mis soluciones:

Ejercicio 1:
[SPOILER][size=80]#include <stdio.h>
#include <stdlib.h>

int inversa(int numerito); {
int retorno=0;
while (numerito>0) {
       retorno=retorno*10+numerito%10;
       numerito=numerito/10;
}
return retorno;
}

int main(int argc, char *argv[]) {
    printf("%d",inversa(atoi(argv[1])));
   
}[/SIZE][/SPOILER]


Ejercicio 2:
[SPOILER][size=80]#include <stdio.h>
#include <stdlib.h>

bool esSufijo(int numerito, int numerazo) {
bool iguales=true;
while (iguales && numerito!=0 && numerazo !=0) {
       iguales=((numerito%10)==(numerazo%10));
       if (iguales) {
          numerito=numerito/10;
          numerazo=numerazo/10;
       }
}
return ((numerito==0)||(numerazo==0));
}


int main(int argc, char *argv[]) {
    if (esSufijo(atoi(argv[1]),atoi(argv[2]))) printf("Si\n");
    else printf("No\n");   
}[/SIZE][/SPOILER]

En este último, si los dos números de la entrada son iguales, te dice que uno es sufijo del otro... se puede controlar facilmente con un IF antes del while.

Probablemente habrá maneras más elegantes de hacerlo (en programas 'pequeños' suelo hacer alguna que otra guarrada..), si en vez de tomar enteros lo tomas como cadena de carácteres tendrías ha hacerlo de forma algo distinta, pero creo que como lo he hecho te puede dar una ligera idea.. [ginyo]
16 respuestas