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

 

 


Tema destacado: Recopilación Tutoriales y Manuales Hacking, Seguridad, Privacidad, Hardware, etc


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 3 4 Ir Abajo Respuesta Imprimir
Autor Tema: [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]  (Leído 34,457 veces)
x64core


Desconectado Desconectado

Mensajes: 1.908


Ver Perfil
[RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]
« en: 4 Enero 2012, 22:41 pm »

Buenas gente bueno recordando hace meses me gustaria hacer un reto y espero que participemos todos :)
bien calentemos primeros :D

RETO: Funcion Extraer Valores Numericos de Cadenas
Ejemplo:
Input: ewiuc3dskhd8nkd62ndsnk9
Ouput: 38629

Teneis hasta 08/01/2012 ese dia se hara el Testing de nuestras funciones , gana la funcion mas optimizada, la mas veloz de todas!
como testear la velocidad de nuestras funciones?
Con la Cabecera: Time.h: http://es.wikipedia.org/wiki/Time.h

Vamos Participemos todos! ;D



edit: edito más reglas un poco tarde viendo las espectativas de algunos codigos :P

* NO VALE ASM INLINE ( sera para el proximo reto, pronto :D )

* la funcion debe de devolver el valor en una variable o como retorno de funcion



Cadena para la prueba de velocidad:


"sdh!w2 28 :-)  9ndk#1@b______dy0--hveybd@  # qism083  s'kl...: su2b7h ++bjsnbvxj77ygv1hiiiioms90nms sjbah b#!1!  --R-E-D--0+-w++ONE***WWW."

RETURN:
"228910083277719010"


« Última modificación: 5 Enero 2012, 22:35 pm por RHL - 该0在 » En línea

BlackZeroX
Wiki

Desconectado Desconectado

Mensajes: 3.158


I'Love...!¡.


Ver Perfil WWW
Re: [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]
« Respuesta #1 en: 4 Enero 2012, 23:23 pm »

Código
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. unsigned int getNumbers(char* szIn, char* szBuffer, size_t sizeBuffer);
  6.  
  7. int main()
  8. {
  9.    char szCadena[] = {"ewiuc3dskhd8nkd62ndsnk9"};
  10.    char* szBuffer = NULL;
  11.    size_t size = getNumbers(szCadena, NULL, 0); // Cuantos numeros hay?...
  12.  
  13.    if (size > 0)
  14.    {
  15.        szBuffer = (char*)malloc(size + 1);
  16.        printf("%d\n", getNumbers(szCadena, szBuffer, size));
  17.        printf("%s\n", szBuffer);
  18.        free(szBuffer);
  19.    }
  20.    getchar();
  21.  
  22.    return EXIT_SUCCESS;
  23. }
  24.  
  25. unsigned int getNumbers(char* szIn, char* szOut, size_t sizeBuffer)
  26. {
  27.    unsigned int iRet = 0;
  28.  
  29.    while(*szIn)
  30.    {
  31.        if (sizeBuffer == 0 && szOut)
  32.            break;
  33.  
  34.        if ((*szIn) >= '0' && '9' >= (*szIn) )
  35.        {
  36.            if (szOut)
  37.            {
  38.                (*szOut++) = (*szIn);
  39.                --sizeBuffer;
  40.            }
  41.            iRet++;
  42.        }
  43.        szIn++;
  44.    }
  45.  
  46.    if (szOut)
  47.        *szOut = (char)0x0;
  48.  
  49.    return iRet;
  50. }
  51.  
  52.  

Código
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. unsigned int getNumbers(char* szIn, char* szBuffer, size_t sizeBuffer);
  6.  
  7. int main()
  8. {
  9.    char szCadena[] = {"ewiuc3dskhd8nkd62ndsnk9"};
  10.    char* szBuffer = NULL;
  11.    size_t size = getNumbers(szCadena, NULL, 0); // Cuantos numeros hay?...
  12.  
  13.    if (size > 0)
  14.    {
  15.        szBuffer = (char*)malloc(size + 1 - 3);
  16.        printf("Se extrayeron: %d de %d\n", getNumbers(szCadena, szBuffer, size - 3), size);
  17.        printf("%s\n", szBuffer);
  18.        free(szBuffer);
  19.    }
  20.    getchar();
  21.  
  22.    return EXIT_SUCCESS;
  23. }
  24.  
  25.  

Dulces Lunas!¡.


« Última modificación: 5 Enero 2012, 01:29 am por BlackZeroX (Astaroth) » En línea

The Dark Shadow is my passion.
Khronos14


Desconectado Desconectado

Mensajes: 443


A lie is a lie


Ver Perfil WWW
Re: [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]
« Respuesta #2 en: 5 Enero 2012, 00:17 am »

Bueno ahí va mi versión, la de BlackZeroX la veo poco superable así que se me ocurrió ir guardando los números en un unsigned long ya que puede ser más práctico.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. unsigned int parseNumbers(char * szStr, unsigned long * uintOut)
  5. {
  6. unsigned int result = 0;
  7.  
  8. if (!(szStr && uintOut))
  9. return result;
  10.  
  11. for (*uintOut = 0; *szStr != 0; szStr++)
  12. if ((*szStr) >= '0' && (*szStr) <= '9')
  13. {
  14. *uintOut = (*uintOut * 10) + (*szStr) - 48;
  15. result++;
  16. }
  17.  
  18. return result;
  19. }
  20.  
  21. int main()
  22. {
  23. char * szCadena = "ewiuc3dskhd8nkd62ndsnk9";
  24. unsigned long numbers = 0;
  25.  
  26. printf("Cantidad de numeros: %d\n", parseNumbers(szCadena, &numbers));
  27. printf("Numbers: %d\n", numbers);
  28.  
  29.  
  30. return 0;
  31. }
  32.  

El algoritmo no tiene mucha ciencia, en cada instancia del bucle que encuentra un número voy multiplicando por 10 y sumándole el nuevo número. El nuevo número lo calculo restándole 48 a su número ASCII.

Se me ocurrió una forma de superar el algoritmo de BlackZeroX, igual mañana la pongo en práctica. Sería recorrer el bucle hasta la mitad e ir comprobando los números por delante y por detrás de la cadena, el problema sería juntar los números de las dos mitades pero en cadenas muy muy largas sería más eficiente.

Saludos.
En línea

BlackZeroX
Wiki

Desconectado Desconectado

Mensajes: 3.158


I'Love...!¡.


Ver Perfil WWW
Re: [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]
« Respuesta #3 en: 5 Enero 2012, 00:57 am »


Se me ocurrió una forma de superar el algoritmo de BlackZeroX, igual mañana la pongo en práctica. Sería recorrer el bucle hasta la mitad e ir comprobando los números por delante y por detrás de la cadena, el problema sería juntar los números de las dos mitades pero en cadenas muy muy largas sería más eficiente.

Saludos.

Al leerte se me ocurrieron 2 formas mas... al rato las pongo en practica xP, igual son lentas en cadenas cortas, pero en cadenas largas uff.

Nota: Modifique mi codigo...

Dulces Lunas!¡.
« Última modificación: 5 Enero 2012, 01:07 am por BlackZeroX (Astaroth) » En línea

The Dark Shadow is my passion.
Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.935


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]
« Respuesta #4 en: 5 Enero 2012, 01:11 am »

C++, solo para ver que tal le va a la STL del compilador que usen para probar  :laugh:

Código
  1. #include <string>
  2. #include <algorithm>
  3. #include <iostream>
  4.  
  5. using namespace std;
  6.  
  7. bool no_es_numero(char c)
  8. {
  9.  return !isdigit(c);
  10. }
  11.  
  12. string &extraer(string &str)
  13. {
  14.  str.resize(remove_if(str.begin(), str.end(), no_es_numero) - str.begin());
  15.  return str;
  16. }
  17.  
  18. void main()
  19. {
  20.  string s = "ewiuc3dskhd8nkd62ndsnk9";
  21.  cout << extraer(s);
  22. }
En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
ace332

Desconectado Desconectado

Mensajes: 66


Ver Perfil
Re: [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]
« Respuesta #5 en: 5 Enero 2012, 01:20 am »

Bueno estoy suponiendo que no hay más de 9 digitos en la cadena (por que sino no caverán en un int)
Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3.  
  4. int extraernum(const char *s);
  5.  
  6. int main()
  7. {
  8.  printf("%d\n",extraernum("ewiuc3dskhd8nkd62ndsnk9"));
  9.  return 0;
  10. }
  11.  
  12. int extraernum(const char *s)
  13. {
  14.  const char *p=s;
  15.  int n=0;
  16.  while(*p)
  17.  {
  18.    if(isdigit(*p)) n=10*n+((*p)-'0');
  19.    p++;
  20.  }
  21.  return n;
  22. }
  23.  

EDIT: No habia leído los códigos de más arriba antes de hacer este post  :-[. En este uso básicamente es el MISMO ALGORITMO que utilizó Kronos14.
« Última modificación: 5 Enero 2012, 18:08 pm por GarbageCollector » En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]
« Respuesta #6 en: 5 Enero 2012, 02:42 am »

Una forma ligeramente distinta en C estándar, utilizando la función strpbrk (prototipo en <string.h>) es:
Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int get_num(char const *s)
  5. {
  6.   int num = 0;
  7.  
  8.   while (s = strpbrk(s, "01234567890"))
  9.      num = num * 10 + *s++ - '0';
  10.  
  11.   return num;
  12. }
  13.  
  14. int main(void)
  15. {
  16.   printf("%d\n", get_num("ewiuc3dskhd8nkd62ndsnk9"));
  17.  
  18.   return 0;
  19. }

Editado: el proceso ahora esta en una funcion.

Un saludo
« Última modificación: 5 Enero 2012, 16:40 pm por rir3760 » 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
x64core


Desconectado Desconectado

Mensajes: 1.908


Ver Perfil
Re: [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]
« Respuesta #7 en: 5 Enero 2012, 03:12 am »

Bueno codes gente! ;D



Bueno estoy suponiendo que no hay más de 9 digitos en la cadena (por que sino no caverán en un int)
Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3.  
  4. int extraernum(const char *s);
  5.  
  6. int main()
  7. {
  8.  printf("%d\n",extraernum("ewiuc3dskhd8nkd62ndsnk9"));
  9.  return 0;
  10. }
  11.  
  12. int extraernum(const char *s)
  13. {
  14.  const char *p=s;
  15.  int n=0;
  16.  while(*p)
  17.  {
  18.    if(isdigit(*p)) n=10*n+((*p)-'0');
  19.    p++;
  20.  }
  21.  return n;
  22. }
  23.  


Lo siento la función debe de aceptar cualquier longitud de cadena, no debe ser fija ( no lo puse en la reglas, perdon)



la mia:
Código
  1. #include "stdio.h"
  2.  
  3. void getnumbers(char* Str, int &v)
  4. {
  5. int c=0;
  6. do{
  7. if((Str[c] >= 0x30) && (Str[c] <= 0x39)){
  8. Str[v]=Str[c];
  9. v++;
  10. }
  11. Str[c]=NULL;
  12. c++;
  13. }while(!(Str[c] == NULL));
  14. }
  15.  
  16. int main()
  17. {
  18. char rSTR[] = {"ewiuc3dskhd8nkd62ndsnk9"};
  19. int nVals = 0x0;
  20.  
  21. getnumbers(rSTR,nVals);
  22. printf("%s\n",rSTR);
  23. printf("%i\n",nVals);
  24.  
  25. return 0;
  26. }
  27.  
  28.  
  29.  
  30.  
En línea

ace332

Desconectado Desconectado

Mensajes: 66


Ver Perfil
Re: [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]
« Respuesta #8 en: 5 Enero 2012, 05:35 am »

No hay cuidado  ;D Ahora el code sí cumple con las especificaciones del problema:

Código
  1. #include <stdio.h>
  2. #include <ctype.h>
  3.  
  4. #define MAX_DIGITOS 1000
  5.  
  6. int extraernum(const char *s, char *n);
  7.  
  8. int main()
  9. {
  10.  char n[MAX_DIGITOS];
  11.  int cdig;
  12.  cdig=extraernum("ewiuc3dskhd8nkd62ndsnk9",n);
  13.  printf("%s\n%d\n",n,cdig);
  14.  return 0;
  15. }
  16.  
  17. int extraernum(const char *s, char *n)
  18. {
  19.  const char *p=s;
  20.  int cdig=0;
  21.  while(*p)
  22.  {
  23.    if(isdigit(*p)) n[cdig++]=*p;
  24.    p++;
  25.  }
  26.  n[cdig]='\0';
  27.  return cdig;
  28. }
  29.  
En línea

BlackZeroX
Wiki

Desconectado Desconectado

Mensajes: 3.158


I'Love...!¡.


Ver Perfil WWW
Re: [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C]
« Respuesta #9 en: 5 Enero 2012, 07:14 am »

@GarbageCollecter
Tu codigo tiene una declaración que es absurda... mas en espesifico const char *p...

Dulces Lunas!¡.

EI: juntando mensajes.

mmm se me ocurre hacer esto (es demasiado CODIGO)...

* Tiene un Bug respecto a la ordenación de los elementos...
* Tiene la ventaja de que deberia de ser el doble de rapido que mi algoritmo normal (Solo si se cuenta con minimos 2 nucleos esto es plena teoria)...

linkear a: libpthread o como se llame en su PC...

Esta funcion el 1er hilo recorre el 0 y numeros PARES, el segundo hilo solo Numeros IMPARES...
Código:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

typedef struct _config
{
    char* szIn;
    char* szOut;
    size_t size;
    size_t start;
    unsigned int* lpPosOut;
    pthread_mutex_t* lpMutex;
}
CONFIG, *LPCONFIG;

void* divideYVenceras(void* arg);
unsigned int getNumbers(char* szIn, char* szOut, size_t size);

int main()
{
    char szCadena[] = {"ewiuc3dskhd8nkd62ndsnk9"};
    char* szBuffer = NULL;
    size_t size = getNumbers(szCadena, NULL, 0); // Cuantos numeros hay?...

    if (size > 0)
    {
        szBuffer = (char*)malloc(size + 1);
        printf("Se extrayeron: %d de %d\n", getNumbers(szCadena, szBuffer, size ), size);
        printf("%s\n", szBuffer);
        free(szBuffer);
    }

    getchar();

    return EXIT_SUCCESS;
}

void*
divideYVenceras(void* arg)
{
    LPCONFIG lpConfig = (LPCONFIG)arg;
    unsigned int iRet = 0;
    unsigned int i = lpConfig->start;

    while(lpConfig->szIn[i])
    {
        if (i > 0 && !lpConfig->szIn[i - 1])
            break;

        if (lpConfig->size < (*lpConfig->lpPosOut) && lpConfig->szOut)
            break;

        if (lpConfig->szIn[i] >= '0' && '9' >= lpConfig->szIn[i] )
        {
            if (lpConfig->szOut)
            {
                pthread_mutex_lock(lpConfig->lpMutex);
                lpConfig->szOut[(*lpConfig->lpPosOut)++] = lpConfig->szIn[i];
                pthread_mutex_unlock(lpConfig->lpMutex);
            }
            iRet++;
        }
        i += 2;
    }

    pthread_exit((void*)iRet);

    //return iRet;  //  No tendria caso...
}

unsigned int
getNumbers(char* szIn, char* szOut, size_t size)
{
    pthread_t pthHilos[2];
CONFIG udtConfig[2];
unsigned int i = 0;
unsigned int lpiRet = 0;
unsigned int iRet = 0;
pthread_mutex_t mutex;

    pthread_mutex_init(&mutex, NULL);

udtConfig[0].szIn = udtConfig[1].szIn = szIn;
udtConfig[0].size = udtConfig[1].size = size;
udtConfig[0].szOut = udtConfig[1].szOut = szOut;
udtConfig[0].start = 0;
udtConfig[1].start = 1;
udtConfig[0].lpPosOut = udtConfig[1].lpPosOut = &i;
udtConfig[0].lpMutex = udtConfig[1].lpMutex = &mutex;

pthread_create(&pthHilos[0], NULL, divideYVenceras, &udtConfig[0]);
pthread_create(&pthHilos[1], NULL, divideYVenceras, &udtConfig[1]);

    pthread_join(pthHilos[0], (void**)&lpiRet);
    iRet = (int)lpiRet;
    pthread_join(pthHilos[1], (void**)&lpiRet);
    iRet += (int)lpiRet;

    pthread_mutex_destroy(&mutex);

    if (szOut)
        szOut[iRet + 1] = (char)0x0;

    return iRet;
}


Codigo Actualizado...

El primer Hilo recorre el 1er trozo de la cadena y el segundo hilo el trozo faltante... se pueden agrenar N hilos si asi se requieren... es RAPIDO con Cadenas LARGAS...

Código
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <pthread.h>
  5.  
  6. typedef struct _config
  7. {
  8.    char* szIn;
  9.    size_t sizeIn;
  10.    char* szOut;
  11.    size_t sizeOut;
  12.    unsigned int* lpPosOut;
  13.    pthread_mutex_t* lpMutex;
  14. }
  15. CONFIG, *LPCONFIG;
  16.  
  17. void* divideYVenceras(void* arg);
  18. unsigned int getNumbers(char* szIn, size_t sizeIn, char* szOut, size_t sizeOut);
  19.  
  20. int main()
  21. {
  22.    char szCadena[] = {"ewiuc3dskhd8nkd62ndsnk9"};
  23.    char* szBuffer = NULL;
  24.    size_t size = getNumbers(szCadena, strlen(szCadena), NULL, 0); // Cuantos numeros hay?...
  25.  
  26.    if (size > 0)
  27.    {
  28.        szBuffer = (char*)malloc(size + 1);
  29.        printf("Se extrayeron: %d de %d\n", getNumbers(szCadena, strlen(szCadena), szBuffer, size ), size);
  30.        printf("%s\n", szBuffer);
  31.        free(szBuffer);
  32.    }
  33.  
  34.    getchar();
  35.  
  36.    return EXIT_SUCCESS;
  37. }
  38.  
  39. void*
  40. divideYVenceras(void* arg)
  41. {
  42.    LPCONFIG lpConfig = (LPCONFIG)arg;
  43.    unsigned int iRet = 0;
  44.  
  45.    if (lpConfig->szIn)
  46.    {
  47.        while(lpConfig->sizeIn-- && *lpConfig->szIn)
  48.        {
  49.            if (lpConfig->sizeOut < (*lpConfig->lpPosOut) && lpConfig->szOut)
  50.                break;
  51.  
  52.            if ((*lpConfig->szIn) >= '0' && '9' >= (*lpConfig->szIn) )
  53.            {
  54.                if (lpConfig->szOut)
  55.                {
  56.                    pthread_mutex_lock(lpConfig->lpMutex);
  57.                    lpConfig->szOut[(*lpConfig->lpPosOut)++] = *lpConfig->szIn;
  58.                    pthread_mutex_unlock(lpConfig->lpMutex);
  59.                }
  60.                iRet++;
  61.            }
  62.            lpConfig->szIn++;
  63.        }
  64.    }
  65.  
  66.    pthread_exit((void*)iRet);
  67.  
  68.    //return iRet;  //  No tendria caso...
  69. }
  70.  
  71. unsigned int
  72. getNumbers(char* szIn, size_t sizeIn, char* szOut, size_t sizeOut)
  73. {
  74.    pthread_t pthHilos[2];
  75.    CONFIG udtConfig[2];
  76.    unsigned int i = 0;
  77.    unsigned int iRet = 0;
  78.    unsigned int iAdd = 0;
  79.    pthread_mutex_t mutex;
  80.  
  81.    pthread_mutex_init(&mutex, NULL);
  82.  
  83. udtConfig[0].szIn = szIn;
  84. udtConfig[0].sizeIn = (sizeIn >> 1);
  85. udtConfig[0].szOut = udtConfig[1].szOut = szOut;
  86. udtConfig[0].sizeOut = udtConfig[1].sizeOut = sizeOut;
  87. udtConfig[0].lpPosOut = udtConfig[1].lpPosOut = &i;
  88. udtConfig[0].lpMutex = udtConfig[1].lpMutex = &mutex;
  89. udtConfig[1].sizeIn = ((udtConfig[0].sizeIn) + (sizeIn & 0x1));
  90. udtConfig[1].szIn = &szIn[(udtConfig[0].sizeIn)];
  91.  
  92. pthread_create(&pthHilos[0], NULL, divideYVenceras, &udtConfig[0]);
  93. pthread_create(&pthHilos[1], NULL, divideYVenceras, &udtConfig[1]);
  94.  
  95.    pthread_join(pthHilos[0], (void**)&iAdd);
  96.    iRet = (int)iAdd;
  97.    pthread_join(pthHilos[1], (void**)&iAdd);
  98.    iRet += (int)iAdd;
  99.  
  100.    pthread_mutex_destroy(&mutex);
  101.  
  102.    if (szOut)
  103.        szOut[iRet + 1] = (char)0x0;
  104.  
  105.    return iRet;
  106. }
  107.  
  108.  

Dulces Lunas!¡.
« Última modificación: 5 Enero 2012, 10:05 am por Eternal Idol » En línea

The Dark Shadow is my passion.
Páginas: [1] 2 3 4 Ir Arriba Respuesta Imprimir 

Ir a:  

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