Ayuda con C++, comparar cadenas sin string.h

transgresor

Tengo que simular el funcionamiento de la funcion strcmp, pero sin usar la libreria string, concretamente me tiene que dar como resultado:
0, si ambas cadenas son iguales
1, si todos los caracteres de una cadena estan incluidos en la otra
2, si no sucede ninguno de los dos casos anteriores

No se como hacerlo, haber si alguien me indica, thx.

Poisonous

Esto iria mejor en el foro de desarrollo.

Como hacerlo, necesitaras un bucle para recorrer ambas cadenas, y luego tendras q añadir un condicional para comparar.

DaRk-eXe

si lo he entendido bien.. podria ser algo a grosso modo tal que...

lo acabo de hacer algo aprisa y corriendo que voy a cenar xD

he supuesto que cad1>=cad2 sino, tienes que hacer un bucle que mire cual de las 2 es la mas larga y sustituir cad1 por la mayor y cad2 por la chica, pero creo que la idea esta bien.

edit: la idea es que cada vez que una comparacion falle, reseteas la cadena chica, asi hasta que termines de recorrer una de las 2 y despues comprobar los resultados.

int wannabe_strcmp(char* cad1,char* cad2) {

int centinela;
int i=0,j=0;

while (cad1[i]!="\0")&&(cad2[j]!="\0") {
	centinela=1;
	if (cad1[i]!=cad2[j]) {
		centinela=0;
		j=-1;
	}
	i++;j++;
}
//si los indices son iguales y centinela es 1 es que las cadenas tambien lo son
if ( (i==j)&&(centinela) ) return 0;

//doy por hecho que la cad2 es como mucho igual de larga o inferior a la cad1. en realidad deberias hacer antes un bucle que compruebe cual es la cadena mas pequeña de 
ambos y sustituir cad1 y cad2 por cadenagrande y cadenachica.

    //si hemos terminado la cadena pequeña completa y el centinela anda a 1 es que la grande contiene a la chica.
if ( (cad2[j]=="\0")&&(centinela) ) return 1;
//si no se cumple alguno de los 2 casos anteriores, pues return 2!!.
return 2;
}


JuAn4k4

Edit : Dios que follon has montao con centinela y el j-- ; ¿ Mas raro no puedes hacerlo no ?

Esto devuelve 1 si "a" es "mayor" que "b" es decir si es más corta o va antes en el abecedario.

int iguales,resultado,i;

iguales =1;
i=0;
while (iguales) && (a[i] !='\0') && (b[i] !='\0') ){
if (a[i] != b[i] ) iguales = 0;
}

if (!iguales) { 
  if (a[i]<b[i]) 
    resultado = 1; 
  else 
    resultado=-1;
} else { 
 if((a[i]=='\0') && (b[i]=='\0') ){resultado=0;}
 else // Puede haber una mas corta. "Paco" y "Pacomacias"
  {  if (a[i]=='\0') 
    resultado = 1; 
  else 
    resultado=-1;
  }
}

return resultado;
DaRk-eXe

lo mismo son las horas y estoy espeso pero..

 while (iguales) && (a[i] !='\0') && (b[i] !='\0') ){
 if (a[i] != b[i] ) iguales = 0;
 } 

te das cuenta que este bucle en cuanto la primera letra no concuerde, se saldrá del bucle sin hacer nada no? xD

edit: es mas.. no incrementas i en ningun lado de tu codigo y en el hipotetico caso de que funcionara.... Para ver si una cadena contiene a otra.. simplemente funciona en tu ejemplo de paco y pacomacias, si yo te doy.. pacomacias y macias no entiendo como funcionaria :\

#7 me explicas mi fail plis?

De verdad que no veo mi fail.. en el momento que a[0]!=b[0], iguales saltará a 0 y no cumplirá la clausula del while y se saldrá :\

#6 no, si tienes razon, falta el incremento de i xD

B

Igual estoy tonto yo también, pero ahí no falta un i++?

#7: No pillo el ok. De C++ no sé nada, pero veo que es muy similar a C. Y no sé, yo en C suelo incrementar las variables en los while :( igual la incrementa de alguna manera hiper molona que no sé, solo quería ayudar xD

EDIT: Si te refieres a que #5 se equivocó y yo no entonces vale xD

LOc0

#5 -> FAIL
#6 -> OK

EDIT: dejo a JuAn4k4 que se explique que para eso se ha currado la funcioncita.

Salu2 ;)

Fyn4r

#5 pero en el siguiente if hace un if (!iguales).

#6 como decía Esteban (aka el barbas de pro) en los bucles siempre aparecen 3 elementos : La salud, el dinero y la videoconsola, y si, que yo sepa falta un i++ pero de C++ igual tengo menos idea que tu xD

DaRk-eXe

ya se que luego hay un if !iguales.. pero de que me sirve mirar condiciones despues si me he parado en la primera letra? nose.. cojo mi hojita y mi papel y no soy capaz de seguir un flujo de datos con sentido :\ lo mismo es que le falta algo de codigo que yo no veo :\

LOc0

#9

A ver, como Juan4k4 debe de estar en la pajilla's hour :P te contesto yo. ¿Cómo demuestras que algo es igual a algo? Pues pones las dos cosas una enfrente de otra y empezando desde la misma posición vas comparando trocito a trocito. Si las dos cosas son del mismo tamaño, llegas al final y todos los trocitos son iguales, ¡BINGO!. SI algún trocito falla pues está claro que no son iguales y entonces comparas los trocitos que fallaron para ver qué cadena es "menor".

Pero en este caso, al comparar cadenas puede haber alguna más larga que la otra, así que si "falla" la comparación de un trocito puede ser porque hayas llegado al final de la cadena corta (da igual que la corta sea la primera o la segunda).

Y sí, falta el incremento del índice, pero es lo que tiene escribir código sin compilador (que es como de verdad se aprende a programar, dicho sea de paso xD...)

Salu2 ;)

B
OFFTOPIC

Yo creo que más o menos he entendido el de Juanaka, básicamente mira si son iguales y si no hace unas cuantas comprobaciones para ver cuál es el mayor, aunque a mí no se me ocurriría esa manera.

DaRk-eXe

#10 enfin.. gracias x la explicacion, debo de ser yo que estoy espeso.. porque por mas que lo miro, ni aun poniendo el i++; no veo que ese bucle funcione bien. (con papel y boli en mano), solo veo que funcione si las 2 cadenas son iguales :\ pero si la primera letra falla.. salta del bucle sin hacer nada ::\

Fyn4r

Pero si la primera letra es distinta, iguales se pone a 0 y ya sabes que no son iguales. O yo lo entiendo muy mal o no se xD

DaRk-eXe

#13 exacto.. y se supone que una puede estar contenida dentro de otra no? es decir..

cad1=Pacomacias

cad2=macias

en ese caso.. no devolveria que una esta contenida en otra.. lo mismo es que soy yo que entendi mal el problema :S

B

#12: Sale del bucle sabiendo que no son iguales. A mí se me ocurre algo más sencillo, pero igual está mal:

  1. Compruebo las longitudes, si una es mayor que otra, devuelvo lo que sea (a menor longitud se considera menor, no?)
  2. En el caso de que sea iguales, comparo caracter a caracter, si difieren hago un return 1 o -1 según el caso (que a > b o viceversa).
  3. Si se acaba el bucle sin salirse, return 0.

Igual es una gilipollez como una casa, ahora mismo estoy muuuuy espeso (llevo bastante rato destripando código y estoy medio tonto).

EDIT: #16: HOSTIA xDDDD. Yo decía lo mismo ajajaja

DaRk-eXe

me da la impresion que aqui cada uno ha hecho una cosa distinta xDDD

bueno.. mas bien yo.. yo he hecho lo que #1 ponia.. 0 si son iguales,1 si una contiene a la otra o 2 en cualquier otro caso..

edit:
a vale vale.. ahora lo entiendo xDD asi que no veia el flujo de datos.. yo andaba buscando lo que decia #1 que tenia que devolver en lugar de pensar en lo que devolvia la funcion strcmp :O xD

LOc0

yo he hecho lo que #1 ponia y juanka a implementado la funcion strcmp xDD --> CASI :P

spoiler

Y ahora sí que me piro.

Salu2 ;)

DaRk-eXe

#17


concretamente me tiene que dar como resultado:
0, si ambas cadenas son iguales
1, si todos los caracteres de una cadena estan incluidos en la otra
2, si no sucede ninguno de los dos casos anteriores

Soleil

una implementación que ví por ahí y me gustó...

int strcmp(const char *s1, const char *s2)
{
    while (*s1 == *s2++)
	if (*s1++ == 0)
		return 0;
    return (*(unsigned char *)s1 - *(unsigned char *)--s2);
}
JuAn4k4

bleh , pon un i++;

pacomacias y macias, macias < pacomacias porque la "m" va antes que la "p".

Ordena alfabeticamente.

El bucle si hace algo, buscas el i-esimo lugar donde una palabra y otra difieren.

Yo implemente el strcmp, no es lo que pedia ? xD

DaRk-eXe

#20 ya ya.. es que yo andaba pensando en lo que puso #1 de lo que debia hacer y devolver su modulo en lugar del strcmp, hemos hecho cosas distintas.

Pues mis dudas tengo sinceramente.. porque pide el strcmp, pero quiere que haga otra cosa, por eso toda la confusion del post. xD

JuAn4k4

Espera, que lo que quiere hacer es mucho mas complicado.

Si los caracteres de una estan contenidos en la otra:

olah y hola, los caracteres de la primera estan incluidos en la segunda.

Soleil

ah coño... pero eso no es lo que hace strcmp...

DaRk-eXe

#22 he querido pensar que se refiere de forma ordenada xDDDD

JuAn4k4

Imagino que si, pero si esta entre-medio, también es complicado.

hola y hholaa también ?

Vamos #1 explicate mejor.

transgresor

Vale, vale, menudo revuelo, haber me explique de culo nose porque puse lo del strcmp creo que no tiene mucho que ver. Introduciendo dos cadenas de caracteres, tengo que obtener los resultados que puse en #1, y me dan esta pista, la cabecera de la funcion sera:

int busca (char *s1, char *s2);
JuAn4k4

Pero dices que devuelves 1 si a es subcadena de b ?

// Es algo raro lo que voy a poner, ya aviso.


i=0;
j=0;
mirarhaciaatras=0;
atras_ok=1;
while ((cad1[i]!='\0')&&(cad2[i]!='\0')) { // Mq no llegues al final de alguna de las dos
if (cad1[i]==cad2[j]) 
{
  //Mirar hacia atras la cadena Si no es igual seguir hacia delante de la segunda cadena.
 if(mirarhaciaatras) {
    mirarhaciaatras=0;
   for(h=0;h<=i-1;h--)
    { atras_ok = (cad1[h]==cad2[j-h-1]) && atras_ok } // Mejor hacer bucle pero es =
  }
 if ( atras_ok) {
 //Seguir hacia delante.
 i++; j++; }
else { j++; miraratras=1;}
}
else { j++; mirarhaciaatras=1;} 
}


if (( cad1[i]=='\0')  && (cad2[i]=='\0') && i ==j )
// SON IGUALES
return ??;

if ( cad1[i]=='\0') 
// cad1 es subcadena de cad2
return ??;

if (cad2[i] == '\0') 
// cad1 no tiene nada que ver con cad2.
return ??;

Es un algoritmo raro pero eficiente, cuando encuentras una discrepancia en lugar de volver a atras sigues hacia delante. La idea la tome de un algoritmo que me explico un compañero en clase que utilizan para reconocimiento de patrones en el adn, creo, o eso me contaba el.

Explico la idea:

abc

lacabdabc

comparaciones:
a - l : NO j++
a -a : SI , atrasOK : i++ j++
b - c : NO , j++
b - b : SI, atras_ok: i++ j++
c - d : NO , j++
c - a: NO j++
c - b : NO j++
c - c : SI , atras_ok: SI , i++, j++
fin: cad1='\0' y cad2='\0' y i!=j

LOc0

Otra opción (vacaciones pow4 XD):

spoiler

Salu2 ;)

JuAn4k4

Esa opcion es la que yo evite, la de volver a atras, ya que no es necesario.

Soleil

#28 Si este foro tuviera karma te daba +10 sólo por el nombre de las variables

Usuarios habituales