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

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Problema con un programa en C (string.h y funciones)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: 1 [2] 3 Ir Abajo Respuesta Imprimir
Autor Tema: Problema con un programa en C (string.h y funciones)  (Leído 6,884 veces)
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Problema con un programa en C (string.h y funciones)
« Respuesta #10 en: 11 Marzo 2014, 11:13 am »

Totalmente de acuerdo engelx, pero también hay considerar a veces que no sólo el código fuente sea más breve, sino que realmente se ejecute más rápido.

Por ejemplo, usas tres veces el strlen(text) es decir una sobrecarga por llamadas a función. Sería mejor definir una constante y asignarle el valor N = strlen(text), luego usas N. Esto quizá lleve más líneas de código fuente pero se ejecutará más rápido.

Aunque aparentemente sea así, por lo que tengo entendido el compilador se encargará de eso de  forma automática

Ya he comprobado que en otras ocasiones el definir una función como inline no produce las mejoras que se esperan de ello ya que al parecer, aunque no la declares como inline, en ocasiones el compilador hace la misma tarea que al declararla inline.


¡¡¡¡ Saluditos! ..... !!!!





« Última modificación: 11 Marzo 2014, 18:33 pm por leosansan » En línea

eferion


Desconectado Desconectado

Mensajes: 1.248


Ver Perfil
Re: Problema con un programa en C (string.h y funciones)
« Respuesta #11 en: 11 Marzo 2014, 11:25 am »

Aunque aparentemente sea saí, por lo que tengo entendido el compilador se encargará de eso de  forma automática

Ya he comprobado que en otras ocasiones el definir una función como inline noproduce las mejoras que se esperan de ello ya que al parecer, aunque no la declares como inline, en ocasiones el compilador hace la misma tarea que al declararla inline.


¡¡¡¡ Saluditos! ..... !!!!




Efectivamente, los compiladores de hoy en día hacen maravillas en cuanto a optimizaciones. De hecho muchos compiladores ignoran el uso de inline y lo aplican a discreción según el código que se encuentren (aunque éste esté en el cpp).

En cualquier caso, si un mismo resultado se va a utilizar varias veces en una misma función siempre queda mejor almacenarlo en una variable que volver a insertar la llamada a la función. De esa forma te aseguras que el código sea más óptimo independientemente de que el compilador optimice de una forma o de otra.


En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Problema con un programa en C (string.h y funciones)
« Respuesta #12 en: 11 Marzo 2014, 16:45 pm »

Por último un detalle sutil. Cuando la longitud N de la palabra sea impar, el cociente N/2 será decimal, pero los tipos de las variables i, N son enteros, por eso la comparación i < N/2 no será válida. Es necesario convertir N a float para que admita los decimales y por eso ponemos i < (float)N / 2.
La conversión al tipo float no es necesaria ya que la división entre dos números enteros resulta en un valor también entero (los decimales se descartan).

----

Una forma ligeramente distinta a las expuestas es:
Código
  1. #include <string.h>
  2.  
  3. int es_palindromo(char const *cad)
  4. {
  5.   int i;
  6.   int j = strlen(cad) - 1;
  7.  
  8.   for (i = 0; i < j && cad[i] == cad[j]; i++, j--)
  9.      ;
  10.  
  11.   return i >= j;
  12. }

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Problema con un programa en C (string.h y funciones)
« Respuesta #13 en: 11 Marzo 2014, 18:14 pm »


Por cierto amigo engelx, en mi caída te arrastré antes y ninguno pusimos los include de cabecera, lo que nos dice que con la emoción no pusimos atención a los warnings que nos lazaba el compilador. Y es que donde esté un "pique" sanote que se quite todo lo demás.


Código
  1. #include <stdio.h>
  2. int main (){
  3.    char text[100];
  4.    int i=0,j=0;
  5.    printf("\n Introduce un texto ");
  6.    gets(text);
  7.    while (text[j++]!='\0');
  8.    for(;text[i]==text[j-i-2] && j/2>i++;);
  9.    printf (i>j/2 ? "\n Es un palindromo ": "\n No es un palindromo ");
  10.    return 0;
  11. }

Aunque tengo un while de más, me ahorro la librería string.h y el repetir strlen en tres ocasiones y además, como ya comentaron anteriormente, el código está más optimizado sin calcular tantas veces strlen.

¡¡¡¡ Saluditos! ..... !!!!


« Última modificación: 11 Marzo 2014, 19:02 pm por leosansan » En línea

do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: Problema con un programa en C (string.h y funciones)
« Respuesta #14 en: 11 Marzo 2014, 19:03 pm »

¡Buenas!

Estaba corrigiendo el código para que tuviese en cuenta los espacios y las eñes, y la parte de los espacios va sobre ruedas, pero por lo menos en Debian no reconoce las eñes, ni introduciendolas como caracteres ni introduciendo sus valores, ni con signo ni sin signo...

¿Alguien puede confirmarmelo?

Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4.  
  5. char mayus(char c)
  6. {
  7.    if(c == 'ñ')
  8.        return 'Ñ';
  9.  
  10.    return toupper(c);
  11. }
  12.  
  13. int palindromo(char *s)
  14. {
  15.    int ini = 0 , fin = strlen(s) - 1;
  16.  
  17.    while(ini < fin)
  18.    {
  19.        while(isspace(s[ini]) && s[ini])
  20.            ini++;
  21.  
  22.        while(isspace(s[fin]) && fin > 0)
  23.            fin--;
  24.  
  25.        if(ini < fin && mayus(s[ini]) != mayus(s[fin]))
  26.            return 0;
  27.  
  28.        ini++;
  29.        fin--;
  30.    }
  31.  
  32.    return 1;
  33. }
  34.  
  35. int main ()
  36. {
  37.    char text[100]="dabale\n \t Arroz a      la zorra el abad";
  38.    char texto[100]="   aMa \n ña ÑamA";
  39.    int i=0;
  40.  
  41.    printf("%d %d\n", (unsigned char)'ñ' , (unsigned char) 'Ñ');
  42.  
  43.    printf("%s",text);
  44.    for(;text[i]==text[strlen(text)-i-1] && strlen(text)/2>i++;);
  45.  
  46.    printf (i>strlen(text)/2 ? "\n Es un palindromo ": "\n No es un palindromo ");
  47.    printf(palindromo(text) ? "\n Es un palindromo ": "\n No es un palindromo ");
  48.    printf(palindromo(texto) ? "\n Es un palindromo ": "\n No es un palindromo ");
  49.  
  50.    return 0;
  51. }
  52.  

¡Saludos!
________________________________________________________________________________________________________

PD: Cambiando la condición isspace por !isalnum ignoraréis cualguier cosa que no sea un caracter o un número (incluida la ñ...). Por ejemplo:
Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4.  
  5. int mayus(int c)
  6. {
  7.    if(c == 'ñ')
  8.        return 'Ñ';
  9.  
  10.    return toupper(c);
  11. }
  12.  
  13. int palindromo(char *s)
  14. {
  15.    int ini = 0 , fin = strlen(s) - 1;
  16.  
  17.    while(ini < fin)
  18.    {
  19.        while(!isalnum(s[ini]) && s[ini++]);
  20.  
  21.        while(!isalnum(s[fin]) && fin-- > 0);
  22.  
  23.        if(ini < fin && mayus(s[ini++]) != mayus(s[fin--]))
  24.            return 0;
  25.    }
  26.  
  27.    return 1;
  28. }
  29.  
  30. int main ()
  31. {
  32.    char texto[100]="a man, \n a p\tlan, a canal, panama";
  33.    int i;
  34.  
  35.    printf("%s",texto);
  36.  
  37.    for(;texto[i]==texto[strlen(texto)-i-1] && strlen(texto)/2>i++;);
  38.  
  39.    printf (i>strlen(texto)/2 ? "\n Es un palindromo ": "\n No es un palindromo ");
  40.    printf(palindromo(texto) ? "\n Es un palindromo ": "\n No es un palindromo ");
  41.  
  42.    return 0;
  43. }
  44.  

Lo de la ñ debe ser porque lo considera un caracter multibyte..., ahora investigo un poco mas.

Con la última modificación ha quedado un poco mas compacto pero un poco menos legible XD.

¡Saludos!
________________________________________________________________________________________________________

sizeof('ñ') en Debian, me está diciendo que son 4 bytes...
« Última modificación: 11 Marzo 2014, 20:51 pm por do-while » En línea

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

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: Problema con un programa en C (string.h y funciones)
« Respuesta #15 en: 11 Marzo 2014, 23:05 pm »

rir3760, no era exactamente eso lo que quería decir. Mi intención era precisamente que sí reconociera los decimales, por ejemplo, si la longitud es N=5 se consideraran los valores i = 0, i = 1, i = 2. O sea todos los valores enteros de i no mayores a 5/2 = 2.5, en cuyo caso debemos convertir a float o double, pues de otro modo la sentencia i < N/2 llegaría sólo hasta i=1.

Claro, ahondando en el fondo vemos que i = 2 no es necesario porque no necesitamos comparar el elemento del medio de la cadena. O sea que al final el (float) sí es redundante.

Pero lo que quiero decir es que en un problema donde se requiriera llegar hasta el elemento del medio i = 2, habría que poner el (float), ya que de otro modo la sentencia i < N/2 con N = 5, llegaría hasta i = 1. Y si se nos ocurre poner i <= N/2 también estaría mal porque en el caso que N sea par, ejemplo N = 6, llegaría hasta i = 3 cuando debería ser hasta i = 2. En un caso como ese creo que no queda otro remedio que i < (float)N/2

En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Problema con un programa en C (string.h y funciones)
« Respuesta #16 en: 12 Marzo 2014, 03:38 am »

Pero lo que quiero decir es que en un problema donde se requiriera llegar hasta el elemento del medio i = 2, habría que poner el (float), ya que de otro modo la sentencia i < N/2 con N = 5, llegaría hasta i = 1. Y si se nos ocurre poner i <= N/2 también estaría mal porque en el caso que N sea par, ejemplo N = 6, llegaría hasta i = 3 cuando debería ser hasta i = 2. En un caso como ese creo que no queda otro remedio que i < (float)N/2.
Si la intención es procesar la primera mitad de un array incluyendo el elemento pivote (si existe) me parece mas sencillo utilizar la expresión "i < (N + 1) / 2" para controlar el bucle.

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: Problema con un programa en C (string.h y funciones)
« Respuesta #17 en: 12 Marzo 2014, 04:00 am »

......................................................................................

Pero lo que quiero decir es que en un problema donde se requiriera llegar hasta el elemento del medio i = 2, habría que poner el (float), ya que de otro modo la sentencia i < N/2 con N = 5, llegaría hasta i = 1. Y si se nos ocurre poner i <= N/2 también estaría mal porque en el caso que N sea par, ejemplo N = 6, llegaría hasta i = 3 cuando debería ser hasta i = 2. En un caso como ese creo que no queda otro remedio que i < (float)N/2



No, no y no. El término central en un array de cindo elementos no es el 2.5 sino el tercero.

Paree que olvidas que los elemento de un array es un caso particular de los términos de una sucesión, que no es más que una aplicación biyectiva entre los números naturales y los elementos de la sucesión .. y entre los números naturales no están los decimales.

El problema se reduce a comparar la sucesión de los elementos de la de parte izquierda con los de la parte derecha y:

* si se trata de un número par se compara exactamente la mitad.

*  si se trata de un número impar se compara la mitad menos uno de cada parte, quedando el central sin nadie con quien compara, por lo que se pasa de él.

De ahí que la expresión N/2 sea la apropiada a emplear.


¡¡¡¡ Saluditos! ..... !!!!



En línea

do-while


Desconectado Desconectado

Mensajes: 1.276


¿Habra que sacarla de paseo?


Ver Perfil
Re: Problema con un programa en C (string.h y funciones)
« Respuesta #18 en: 12 Marzo 2014, 08:56 am »

Ese algoritmo tiene grades fallos lógicos:

O bien la cadena tiene que ser simétrica con respecto al centro o no puede contener espacios.

Dado que hay palíndromos que contienen espacios y que no son simétricos os dirá que textos que realmente son palíndromos no lo son (ej: Anita lava la tina).  Lo de los espacios lo podéis arreglar añadiendo una función que los elimine. De todas todas tenéis que corregir el código.

¡Saludos!
En línea

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

Desconectado Desconectado

Mensajes: 254



Ver Perfil WWW
Re: Problema con un programa en C (string.h y funciones)
« Respuesta #19 en: 13 Marzo 2014, 01:39 am »

Si la intención es procesar la primera mitad de un array incluyendo el elemento pivote (si existe) me parece mas sencillo utilizar la expresión "i < (N + 1) / 2" para controlar el bucle.

Es otra manera, gracias.

Para do-while, la solución que presenté considera que la palabra no contiene espacios, y fue así para mantenerme fiel al enfoque dado inicialmente al tema por parte de su autor. Luego él mencionó el problema de los espacios, y creo que después presentó en un programa capaz de manejar ese problema.

Leosansan ya va tranquilo, calma. Por supuesto que el elemento central de una sucesión de cinco elementos no es el 2.5, sino el 2 (o sea, de índice 2). Se trataba de una condición que pudiera discernir los valores correctos de i a tomar. Al redondear a enteros, la condición i < 2.5 se reduce a i = 0, 1, 2, como queríamos.

O más precisamente, tal como rir3760 y tú dicen la condición i< N/2 es la apropiada si para el caso impar no se toma el elemento central (el caso nuestro), y la condición i < (float)N / 2, o bien i < (N+1)/2 si el elemento central fuera tomado (que no es nuestro caso).

Pero yo tuve un lapsus y por alguna razón incluí el elemento central o pivote, de donde surgió toda la discusión. Conste que incluir este pivote no afecta el resultado del programa, por cuánto estaría comparando dicho elemento consigo mismo y a lo peor incurre en una pequeña falta de eficiencia.
En línea

Saludos, Yoel.
P.D..-   Para mayores dudas, puedes enviarme un mensaje personal (M.P.)
Páginas: 1 [2] 3 Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines