elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Sigue las noticias más importantes de seguridad informática en el Twitter! de elhacker.NET


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Comparar cadenas sin usar strcmp
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Comparar cadenas sin usar strcmp  (Leído 20,491 veces)
Rockmore

Desconectado Desconectado

Mensajes: 18



Ver Perfil
Comparar cadenas sin usar strcmp
« en: 23 Octubre 2010, 21:13 pm »

Saludos a todos. Llevo días con sus noches dándole mil vueltas a esto y en todos los lados que encuentro, leo que la alternativa es hacerlo a mano, pero no sé qué es a mano en este caso.

Mi caso es que tengo que escribir dos nombres con sus dos apellidos, unirlos en una cadena con espacios y ordenarlos lexicográficamente sin utilizar strcmp.

Este es el código que tengo hecho:

Código
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<conio.h>
  4. //Librerías
  5.  
  6. int main(void){
  7. int nombre1,nombre2,let,primero=1,segundo=1,iguales=0;
  8. char nom1[50],apuno1[50],apdos1[50],nom2[50],apuno2[50],apdos2[50],esp[1];
  9. //Declaración de variables cadena
  10.  
  11. strcpy(esp," ");
  12. //Cadena espacio
  13.  
  14. printf("Nombre de la primera persona: ");
  15. gets(nom1);
  16. printf("\nPrimer apellido de la primera persona: ");
  17. gets(apuno1);
  18. printf("\nSegundo apellido de la primera persona: ");
  19. gets(apdos1);
  20. printf("\nNombre de la segunda persona: ");
  21. gets(nom2);
  22. printf("\nPrimer apellido de la segunda persona: ");
  23. gets(apuno2);
  24. printf("\nSegundo apellido de la segunda persona: ");
  25. gets(apdos2);
  26. //Petición de datos
  27.  
  28. strcat(nom1,esp);
  29. strcat(nom1,apuno1);
  30. strcat(nom1,esp);
  31. strcat(nom1,apdos1);
  32. strcat(nom2,esp);
  33. strcat(nom2,apuno2);
  34. strcat(nom2,esp);
  35. strcat(nom2,apdos2);
  36. //Concatenación de cadenas
  37.  
  38. nombre1=strlen(nom1);
  39. nombre2=strlen(nom2);
  40. //Contador de caracteres
  41.  
  42. if(nombre1<=nombre2){
  43. for(let=0;primero!=0||segundo!=0||iguales!=nombre1;let++){
  44. if(nom1[let]<nom2[let]){
  45. primero=0;
  46. }
  47. else if(nom1[let]>nom2[let]){
  48. segundo=0;
  49. }
  50. else if(nom1[let]==nom2[let]){
  51. iguales++;
  52. }
  53. }
  54. }else{
  55. for(let=0;primero!=0||segundo!=0||iguales!=nombre2;let++){
  56. if(nom1[let]<nom2[let]){
  57. primero=0;
  58. }
  59. else if(nom1[let]>nom2[let]){
  60. segundo=0;
  61. }
  62. else if(nom1[let]==nom2[let]){
  63. iguales++;
  64. }
  65. }
  66. }//Comparación de letras
  67.  
  68. if(primero==0||iguales==nombre1){
  69. printf("\nLos nombres ordenados son:\n%s\n%s",nom1,nom2);
  70. }else if (segundo==0||iguales==nombre2){
  71. printf("\nLos nombres ordenados son:\n%s\n%s",nom2,nom1);
  72. }else{
  73. printf("\nLos nombres ordenados son:\n%s\n%s",nom2,nom1);
  74. }//Resultado
  75.  
  76. getche();
  77. return(0);
  78. }

Los nombres los coge bien, y al final están bien unidos en la cadena, pero no los ordena, el primer nombre que escribo es el primero que aparece, y si pongo dos nombres exactamente iguales, me salta un error en la ejecución, aunque compila bien. El compilador que utilizo es el Qt Creator de Nokia, que es el que se utiliza en la universidad.

Espero y agradezco sobremanera cualquier tipo de ayuda.


« Última modificación: 23 Octubre 2010, 21:16 pm por Littlehorse » En línea

Oblivi0n


Desconectado Desconectado

Mensajes: 392

Odio las ranas.


Ver Perfil
Re: Comparar cadenas sin usar strcmp
« Respuesta #1 en: 24 Octubre 2010, 03:22 am »

Usas demasiadas lineas para algo muy simple.
Las cadenas son arrays de caracteres.
Como las cadenas a comparar no son constantes, puedes hacer un bucle que cuente la longitud de la cadena, y luego otro bucle que vaya comparando los sucesivos elementos del array hasta que encuentre alguno diferente (si lo encuentra...)


En línea

Rockmore

Desconectado Desconectado

Mensajes: 18



Ver Perfil
Re: Comparar cadenas sin usar strcmp
« Respuesta #2 en: 24 Octubre 2010, 19:28 pm »

Buenas. ¿Lo de los bucles me ha parecido entender que ponga un for (por ejemplo) para contar caracteres y otro para somprarar letras?

Para contar caracteres tengo el strlen metido en las variables nombre1 y nombre2, para que si una cadena es más corta, mediante la variable iguales cuente las que son iguales hasta que finalice la cadena más corta, con lo que se saldría del bucle de comparación.

He vuelto a reescribir esa parte, en lugar de con <, >, o ==, restando los caracteres y la diferencia, según sea mayor, menor o igual que cero, un poco al estilo strcmp.

Poniendo caracteres arbitrariamente fuera de cualquier bucle, la resta me la hace perfecta, si la primera es G y la segunda B, el resultado es 5, y si son B y G, me da -5. Eso es lo que yo necesito para resolver el programa.

Pues bien, al aplicarlo poniendo una variable tal que así nom1[let] la resta siempre es 0, por eso no me reordena nada. Y nuevamente, si pongo dos cadenas exactamente iguales, compila sin problemas, pero a la hora de entrar en el bucle, salta un error de ejecución.

Este es el nuevo código, aunque es muy parecido al anterior:

Código:
#include<stdio.h>
#include<string.h>
#include<conio.h>
//Librerías

int main(void){
 int dif,long1,long2,let,same=0,prim,seg;
 char nom1[50],apuno1[50],apdos1[50],nom2[50],apuno2[50],apdos2[50],esp[1];
 //Declaración de variables cadena

 strcpy(esp," ");
 //Cadena espacio

 printf("Nombre de la primera persona: ");
 gets(nom1);
 printf("\nPrimer apellido de la primera persona: ");
 gets(apuno1);
 printf("\nSegundo apellido de la primera persona: ");
 gets(apdos1);
 printf("\nNombre de la segunda persona: ");
 gets(nom2);
 printf("\nPrimer apellido de la segunda persona: ");
 gets(apuno2);
 printf("\nSegundo apellido de la segunda persona: ");
 gets(apdos2);
 //Petición de datos

 strcat(nom1,esp);
 strcat(nom1,apuno1);
 strcat(nom1,esp);
 strcat(nom1,apdos1);
 strcat(nom2,esp);
 strcat(nom2,apuno2);
 strcat(nom2,esp);
 strcat(nom2,apdos2);
 //Concatenación de cadenas

 long1=strlen(nom1);
 long2=strlen(nom2);
 //Contador de caracteres

 if(long1<=long2){
     for(let=0;prim!=0||seg!=0||same!=long1;let++){
         dif=nom1[let]-nom2[let];
         if(dif>0){
             prim=0;
         }else if(dif<0){
             seg=0;
         }else{
             same++;
         }
     }
 }else{
     for(let=0;prim!=0||seg!=0||same!=long2;let++){
         dif=nom1[let]-nom2[let];
         if(dif>0){
             prim=0;
         }else if(dif<0){
             seg=0;
         }else{
             same++;
         }
     }
 }//Comparación de caracteres

 printf("Iguales: %d",same);
 printf("Diferencia: %d",dif);
 printf("\nPrimer nombre: %s\nSegundo nombre: %s",nom1,nom2);
 getche();
 return(0);
}

Los printf del final están sólamente a modo de comprobación de datos, no muestran el resultado que necesito, ya que las restas no se hacen como deberían.
En línea

xassiz~


Desconectado Desconectado

Mensajes: 457



Ver Perfil WWW
Re: Comparar cadenas sin usar strcmp
« Respuesta #3 en: 24 Octubre 2010, 20:22 pm »

Te dejo un ejemplo:
Código
  1. #include<stdio.h>
  2. #include<string.h>
  3.  
  4. //Compara cadenas - by pablomi
  5.  
  6. int main()
  7. {
  8.    int i, comparacion;
  9.  
  10.    char cadena1[50] = "Hola";
  11.    char cadena2[50] = "Adios";
  12.  
  13.    for(i=0;i<strlen(cadena1);i++){
  14.        if(cadena1[i]!=cadena2[i])
  15.            comparacion = 1;
  16.        else
  17.            comparacion = 0;
  18.    }
  19.  
  20.    if(comparacion==1)
  21.        printf("Son distintas\n");
  22.    else
  23.        printf("Son iguales\n");
  24.  
  25.    return 0;
  26. }
En línea

Rockmore

Desconectado Desconectado

Mensajes: 18



Ver Perfil
Re: Comparar cadenas sin usar strcmp
« Respuesta #4 en: 24 Octubre 2010, 22:33 pm »

Vale, vale. Ya me va saliendo. Pero aún queda algo que depurar, ya que al meter como primer nombre "bb bb bb" y como segundo "bbb bbb bbb", me ordena como primero el largo y luego el corto, cuando tendría que ser al revés.

Esta es la parte del código cambiada:

Código:
for(let=0;let<strlen(nom1);let++){
    if(nom1[let]!=nom2[let]){
        comp=1;
    }else
        comp=0;
    }
 //Comparación de cadenas

 if(comp==1){
     for(let=0;let<strlen(nom1);let++){
         if(nom1[let]<nom2[let]){
             ord=1;
         }else if(nom2[let]<nom1[let]){
             ord=2;
         }
      }
 }else{
     printf("\nNombres ordenados:\n%s\n%s",nom1,nom2);
 }//Comparación de letras

 if(ord==1){
     printf("\nNombres ordenados:\n%s\n%s",nom1,nom2);
 }else if(ord==2){
     printf("\nNombres ordenados:\n%s\n%s",nom2,nom1);
 }//Muestra de resultado

¿Debería crear un bucle comparador según si el strlen de la primera cadena es más largo que el segundo y viceversa, o hay algún otro modo que consuma menos recursos y ocupe menos líneas?
En línea

PiroskY

Desconectado Desconectado

Mensajes: 76


пирожки


Ver Perfil
Re: Comparar cadenas sin usar strcmp
« Respuesta #5 en: 25 Octubre 2010, 00:18 am »

Te dejo un ejemplo:
Codigo
Cuidad con tu codigo, si la ultima letra de cada cadena coincide dice que son iguales, ej
Holaaaaaaaaaaaa
Nadaqueveraaaaa
Código
  1. #include<stdio.h>
  2. #include<string.h>
  3.  
  4. //Compara cadenas - by pablomi
  5.  
  6. int main()
  7. {
  8.    int i, comparacion = 0;
  9.  
  10.    char cadena1[50] = "Hola";
  11.    char cadena2[50] = "Adios";
  12.  
  13.    for(i=0;i<strlen(cadena1);i++){
  14.        if(cadena1[i]!=cadena2[i])
  15.            comparacion = 1;
  16.  
  17.    if(comparacion==1)
  18.        printf("Son distintas\n");
  19.    else
  20.        printf("Son iguales\n");
  21.  
  22.    return 0;
  23. }

ahi quedaria bien

Fijate de corregir eso, rockmore

Btw: Tene en cuenta que el strcmp ordena esciimente, no alfabeticamente
Para el strcmp Belen va antes que ana porque en el ascii las mayusculas estan primero

¿Debería crear un bucle comparador según si el strlen de la primera cadena es más largo que el segundo y viceversa, o hay algún otro modo que consuma menos recursos y ocupe menos líneas?
yo en tu lugar usaria una variable donde guardo la cantidad de letras que tiene la cadena mas corta, y uso esa variable para las vueltas del for
« Última modificación: 25 Octubre 2010, 00:23 am por PiroskY » En línea

Rockmore

Desconectado Desconectado

Mensajes: 18



Ver Perfil
Re: Comparar cadenas sin usar strcmp
« Respuesta #6 en: 25 Octubre 2010, 02:26 am »

Casi, casi. Si las cadenas son distintas, ordena de lujo. Si son iguales, se fija en la última letra: "aaa aaa aaa" va antes que "bbb bbb bbb", pero "bbb bbb bba" va antes que "aaa aaa aab"

Código:
long1=strlen(nom1);
 long2=strlen(nom2);
 if(long1<=long2){
     longdef=long2;
 }else{
     longdef=long1;
 }//Contador de caracteres

 for(let=0;let<longdef;let++){
    if(nom1[let]!=nom2[let]){
        comp=1;
    }
}//Comparación de cadenas

 if(comp==1){
     for(let=0;let<longdef;let++){
         if(nom1[let]<nom2[let]){
             ord=1;
         }else if(nom2[let]<nom1[let]){
             ord=2;
         }
      }
 }//Comparación de letras

 if(ord==1){
     printf("\nNombres ordenados:\n%s\n%s",nom1,nom2);
 }else{
     printf("\nNombres ordenados:\n%s\n%s",nom2,nom1);
 }//Muestra de resultado

 getche();
 return(0);
}

Este código es cada vez más surrealista. Había pensado en poner algún tipo de contador, o una condición que rompiese el bucle, de modo que la primera condición que cambie alguna variable, se quedase así, como en el primer código que hice:

Código:
for(let=0;ord!=1&&ord!=2&&let<longdef;let++)

Edit: Justo eso era lo que necesitaba. Ahora sí que creo que está impecable. Gracias a todos por las indicaciones
« Última modificación: 25 Octubre 2010, 02:52 am por Rockmore » En línea

PiroskY

Desconectado Desconectado

Mensajes: 76


пирожки


Ver Perfil
Re: Comparar cadenas sin usar strcmp
« Respuesta #7 en: 25 Octubre 2010, 03:08 am »

EDITO:
volviendo a mirar tu codigo, note
Código
  1. if(comp==1){
  2.     for(let=0;let<longdef;let++){
  3.         if(nom1[let]<nom2[let]){
  4.             ord=1;
  5.         }else if(nom2[let]<nom1[let]){
  6.             ord=2;

Estas teniendo el mismo problema que pablomi
Vos tenes que poner la variable en un estado, y cambiarlo si encuentra letras que no coincide, pero no volver a ponerle en el estado inicial si encuentra despues coincidencias

Si no interpreto mal, esa parte de codigo hace que lo unico que importe son, la ultima letra de la cadena corta, y la de la misma posicion de la larga, dependiendo de esas dos te va a ordenar las cadenas

Lo arreglas poniendole el for que mencionas, porque cuando ord pasa a valer 1 o 2, el for deja de correr, deja el codigo como lo posteaste y ponele un "break;" abajo de ord=1; y ord=2;
eso hace que cuando encuentre 2 letras distintas, guarde en ord cual de los 2 mostras primero y el break te saca del ciclo for, y no necesitas complicar las condiciones del for
« Última modificación: 25 Octubre 2010, 03:25 am por PiroskY » En línea

do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: Comparar cadenas sin usar strcmp
« Respuesta #8 en: 25 Octubre 2010, 03:45 am »

¡Buenas!

hace mucho que no pongo codigos... pero viendo que la gente se anima...

Código
  1.  
  2. /*
  3.  * mystrcmp < 0 si s1 < s2
  4.  * mystrcmp ==0 si s1 == s2
  5.  * mystrcmp > 0 si s1 > s2
  6.  */
  7. int mystrcmp(char* s1,char* s2)
  8. {
  9.    for(; *s1 && *s2 && (*s1) == (*s2) ; s1++ , s2++);
  10.  
  11.    return ((*s1) - (*s2));
  12. }
  13.  
  14.  

Eso si trabajas con funciones, sino en tu codigo podrias poner

Código
  1. for(i = 0 ; nom1[i] && nom2[i] && nom1[i] == nom2[i] ; i++);
  2.  
  3. ord = nom1[i] - nom2[i]; /* y ord tendra los valores de la funcion anterior */
  4.  

Espero no haberme confundido, ya que ni siquiera he probado el codigo...  :silbar:

¡Saludos!
En línea

- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!
PiroskY

Desconectado Desconectado

Mensajes: 76


пирожки


Ver Perfil
Re: Comparar cadenas sin usar strcmp
« Respuesta #9 en: 25 Octubre 2010, 03:53 am »

Código
  1. for(i = 0 ; nom1[i] && nom2[i] && nom1[i] == nom2[i] ; i++);
  2.  
  3. ord = nom1[i] - nom2[i]; /* y ord tendra los valores de la funcion anterior */
  4.  

No entiendo como definiste el for, me explicas?
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Intento comparar cadenas [novato] « 1 2 3 »
Programación C/C++
barnix456 20 12,286 Último mensaje 7 Mayo 2012, 20:37 pm
por barnix456
¿Comparar dos cadenas de caracteres en php?
PHP
Netstat89 5 10,833 Último mensaje 1 Octubre 2012, 21:21 pm
por Shell Root
Ayuda: Recorrer cadenas usando strcmp (alternativas), carácter '/0'.
Programación C/C++
Tolkien 2 2,311 Último mensaje 5 Junio 2014, 17:28 pm
por Tolkien
[C] Comparar 2 cadenas sin usar <string.h> « 1 2 »
Programación C/C++
Ataulfo7 16 10,454 Último mensaje 9 Abril 2015, 19:22 pm
por Miseryk
ay forma de comparar 2 cadenas sin strcmp
Programación C/C++
masterkeyes 5 4,164 Último mensaje 17 Agosto 2015, 15:30 pm
por ivancea96
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines