Tema destacado: Suscripción al boletín mensual de elhacker.net
Autor
|
Tema: [RETO] + Funcion Extraer Numeros de Cadenas! [Cpp/C] (Leído 4,112 veces)
|
RHL
Conectado
Mensajes: 968
mental
|
Buenas gente bueno recordando hace meses me gustaria hacer un reto y espero que participemos todos  bien calentemos primeros RETO: Funcion Extraer Valores Numericos de CadenasEjemplo: Input: ewiuc 3dskhd 8nkd 62ndsnk 9Ouput: 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.hVamos Participemos todos! 
edit: edito más reglas un poco tarde viendo las espectativas de algunos codigos * NO VALE ASM INLINE ( sera para el proximo reto, pronto )* 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 por RHL - 该0在 »
|
En línea
|
|
|
|
BlackZeroX (Astaroth)
Wiki
Desconectado
Mensajes: 2.831
I'Love...!¡.
|
#include <stdio.h> #include <stdlib.h> unsigned int getNumbers(char* szIn, char* szBuffer, size_t sizeBuffer); 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("%d\n", getNumbers(szCadena, szBuffer, size)); printf("%s\n", szBuffer); free(szBuffer); } getchar(); return EXIT_SUCCESS; } unsigned int getNumbers(char* szIn, char* szOut, size_t sizeBuffer) { unsigned int iRet = 0; while(*szIn) { if (sizeBuffer == 0 && szOut) break; if ((*szIn) >= '0' && '9' >= (*szIn) ) { if (szOut) { (*szOut++) = (*szIn); --sizeBuffer; } iRet++; } szIn++; } if (szOut) *szOut = (char)0x0; return iRet; } #include <stdio.h> #include <stdlib.h> unsigned int getNumbers(char* szIn, char* szBuffer, size_t sizeBuffer); 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 - 3); printf("Se extrayeron: %d de %d\n", getNumbers(szCadena, szBuffer, size - 3), size); printf("%s\n", szBuffer); free(szBuffer); } getchar(); return EXIT_SUCCESS; } Dulces Lunas!¡.
|
|
|
|
« Última modificación: 5 Enero 2012, 01:29 por BlackZeroX (Astaroth) »
|
En línea
|
|
|
|
Khronos14
Desconectado
Mensajes: 285
A lie is a lie
|
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. #include <stdio.h> #include <stdlib.h> unsigned int parseNumbers(char * szStr, unsigned long * uintOut) { unsigned int result = 0; if (!(szStr && uintOut)) return result; for (*uintOut = 0; *szStr != 0; szStr++) if ((*szStr) >= '0' && (*szStr) <= '9') { *uintOut = (*uintOut * 10) + (*szStr) - 48; result++; } return result; } int main() { char * szCadena = "ewiuc3dskhd8nkd62ndsnk9"; unsigned long numbers = 0; printf("Cantidad de numeros: %d\n", parseNumbers(szCadena, &numbers)); printf("Numbers: %d\n", numbers); getchar(); return 0; } 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 (Astaroth)
Wiki
Desconectado
Mensajes: 2.831
I'Love...!¡.
|
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 por BlackZeroX (Astaroth) »
|
En línea
|
|
|
|
|
Eternal Idol
|
C++, solo para ver que tal le va a la STL del compilador que usen para probar  #include <string> #include <algorithm> #include <iostream> using namespace std; bool no_es_numero(char c) { return !isdigit(c); } string &extraer(string &str) { str.resize(remove_if(str.begin(), str.end(), no_es_numero) - str.begin()); return str; } void main() { string s = "ewiuc3dskhd8nkd62ndsnk9"; cout << extraer(s); }
|
|
|
|
|
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
Mensajes: 66
|
Bueno estoy suponiendo que no hay más de 9 digitos en la cadena (por que sino no caverán en un int) #include <stdio.h> #include <ctype.h> int extraernum(const char *s); int main() { printf("%d\n",extraernum("ewiuc3dskhd8nkd62ndsnk9")); return 0; } int extraernum(const char *s) { const char *p=s; int n=0; while(*p) { if(isdigit(*p)) n=10*n+((*p)-'0'); p++; } return n; } 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 por GarbageCollector »
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 382
|
Una forma ligeramente distinta en C estándar, utilizando la función strpbrk (prototipo en <string.h>) es: #include <stdio.h> #include <string.h> int get_num(char const *s) { int num = 0; while (s = strpbrk(s, "01234567890")) num = num * 10 + *s++ - '0'; return num; } int main(void) { printf("%d\n", get_num("ewiuc3dskhd8nkd62ndsnk9")); return 0; } Editado: el proceso ahora esta en una funcion. Un saludo
|
|
|
|
« Última modificación: 5 Enero 2012, 16:40 por rir3760 »
|
En línea
|
The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz
|
|
|
RHL
Conectado
Mensajes: 968
mental
|
Bueno codes gente! 
Bueno estoy suponiendo que no hay más de 9 digitos en la cadena (por que sino no caverán en un int) #include <stdio.h> #include <ctype.h> int extraernum(const char *s); int main() { printf("%d\n",extraernum("ewiuc3dskhd8nkd62ndsnk9")); return 0; } int extraernum(const char *s) { const char *p=s; int n=0; while(*p) { if(isdigit(*p)) n=10*n+((*p)-'0'); p++; } return n; } 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: #include "stdio.h" void getnumbers(char* Str, int &v) { int c=0; do{ if((Str[c] >= 0x30) && (Str[c] <= 0x39)){ Str[v]=Str[c]; v++; } Str[c]=NULL; c++; }while(!(Str[c] == NULL)); } int main() { char rSTR[] = {"ewiuc3dskhd8nkd62ndsnk9"}; int nVals = 0x0; getnumbers(rSTR,nVals); printf("%s\n",rSTR); printf("%i\n",nVals); return 0; }
|
|
|
|
|
En línea
|
|
|
|
ace332
Desconectado
Mensajes: 66
|
No hay cuidado  Ahora el code sí cumple con las especificaciones del problema: #include <stdio.h> #include <ctype.h> #define MAX_DIGITOS 1000 int extraernum(const char *s, char *n); int main() { char n[MAX_DIGITOS]; int cdig; cdig=extraernum("ewiuc3dskhd8nkd62ndsnk9",n); printf("%s\n%d\n",n,cdig); return 0; } int extraernum(const char *s, char *n) { const char *p=s; int cdig=0; while(*p) { if(isdigit(*p)) n[cdig++]=*p; p++; } n[cdig]='\0'; return cdig; }
|
|
|
|
|
En línea
|
|
|
|
BlackZeroX (Astaroth)
Wiki
Desconectado
Mensajes: 2.831
I'Love...!¡.
|
@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... #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... #include <stdio.h> #include <stdlib.h> #include <pthread.h> typedef struct _config { char* szIn; size_t sizeIn; char* szOut; size_t sizeOut; unsigned int* lpPosOut; pthread_mutex_t* lpMutex; } CONFIG, *LPCONFIG; void* divideYVenceras(void* arg); unsigned int getNumbers(char* szIn, size_t sizeIn, char* szOut, size_t sizeOut); int main() { char szCadena[] = {"ewiuc3dskhd8nkd62ndsnk9"}; char* szBuffer = NULL; size_t size = getNumbers(szCadena, strlen(szCadena), NULL, 0); // Cuantos numeros hay?... if (size > 0) { szBuffer = (char*)malloc(size + 1); printf("Se extrayeron: %d de %d\n", getNumbers(szCadena, strlen(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; if (lpConfig->szIn) { while(lpConfig->sizeIn-- && *lpConfig->szIn) { if (lpConfig->sizeOut < (*lpConfig->lpPosOut) && lpConfig->szOut) break; if ((*lpConfig->szIn) >= '0' && '9' >= (*lpConfig->szIn) ) { if (lpConfig->szOut) { pthread_mutex_lock(lpConfig->lpMutex); lpConfig->szOut[(*lpConfig->lpPosOut)++] = *lpConfig->szIn; pthread_mutex_unlock(lpConfig->lpMutex); } iRet++; } lpConfig->szIn++; } } pthread_exit((void*)iRet); //return iRet; // No tendria caso... } unsigned int getNumbers(char* szIn, size_t sizeIn, char* szOut, size_t sizeOut) { pthread_t pthHilos[2]; CONFIG udtConfig[2]; unsigned int i = 0; unsigned int iRet = 0; unsigned int iAdd = 0; pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL); udtConfig[0].szIn = szIn; udtConfig[0].sizeIn = (sizeIn >> 1); udtConfig[0].szOut = udtConfig[1].szOut = szOut; udtConfig[0].sizeOut = udtConfig[1].sizeOut = sizeOut; udtConfig[0].lpPosOut = udtConfig[1].lpPosOut = &i; udtConfig[0].lpMutex = udtConfig[1].lpMutex = &mutex; udtConfig[1].sizeIn = ((udtConfig[0].sizeIn) + (sizeIn & 0x1)); udtConfig[1].szIn = &szIn[(udtConfig[0].sizeIn)]; pthread_create(&pthHilos[0], NULL, divideYVenceras, &udtConfig[0]); pthread_create(&pthHilos[1], NULL, divideYVenceras, &udtConfig[1]); pthread_join(pthHilos[0], (void**)&iAdd); iRet = (int)iAdd; pthread_join(pthHilos[1], (void**)&iAdd); iRet += (int)iAdd; pthread_mutex_destroy(&mutex); if (szOut) szOut[iRet + 1] = (char)0x0; return iRet; } Dulces Lunas!¡.
|
|
|
|
« Última modificación: 5 Enero 2012, 10:05 por Eternal Idol »
|
En línea
|
|
|
|
|
El_Java
|
Aquí os dejo mi versión, tiene complejidad O(str.size()): EDITO: Pongo el algoritmo como forma de función, thanks EI#include <iostream> #include <cctype> using namespace std; string extraer(const string &str){ string aux; for(int a=0; a<(int)str.size(); a++) if(isdigit(str[a])) aux.push_back(str[a]); return aux; } int main(){ string str; str = "ewiuc3dskhd8nkd62ndsnk9"; //cin >> str; str = extraer(str); cout << str << endl; return 0; }
|
|
|
|
« Última modificación: 5 Enero 2012, 22:49 por El_Java »
|
En línea
|
|
|
|
|
Eternal Idol
|
La verdad es que los requisitos no estan bien definidos pero me parece que se pidio una FUNCION. ¿Con un codigo solo ya es suficiente, no?
|
|
|
|
|
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
|
|
|
|
|
rir3760
Desconectado
Mensajes: 382
|
El algoritmo (procesar cada carácter de forma secuencial) esta bien. Lo que si hay que cambiar son algunos detalles como los nombres de los encabezados (deberían ser <cstdio> y <cstring>) y evitar el uso de la función "gets". Tampoco utilizas el valor de retorno de la función (en lugar de imprimir cada dígito debes calcular el numero y retornarlo). Para el caso te conviene leer el tema |Lo que no hay que hacer en C/C++. Nivel basico|. Un saludo
|
|
|
|
|
En línea
|
The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz
|
|
|
|
Eternal Idol
|
alexis33de: empujar el resultado de extraer en cout no tiene ningun sentido, lo unico que logras es escribir un 0 que no es parte del input en pantalla (en mi codigo sirve para imprimir la cadena que retorna mi funcion).
|
|
|
|
|
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
|
|
|
|
| Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
App para buscar info y cadenas de numeros en MYSQL
Programación Visual Basic
|
A2Corp
|
2
|
1,575
|
14 Mayo 2008, 18:47
por odeONeSs
|
|
|
RETO saber elcodigo de encriptacion de estas cadenas de texto
Criptografía
|
riscking
|
3
|
2,043
|
18 Agosto 2008, 03:12
por riscking
|
|
|
[RETO] Funcion iFactorize() - Factorizacion de numeros enteros
« 1 2 »
Programación Visual Basic
|
Karcrack
|
15
|
2,942
|
19 Julio 2010, 17:19
por FFernandez
|
|
|
Reto: Números primos en python
Ejercicios
|
Novlucker
|
6
|
2,858
|
24 Noviembre 2010, 16:02
por Novlucker
|
|
|
[RETO] + Funcion Extraer Numeros de Cadenas!
« 1 2 3 4 »
Programación Visual Basic
|
RHL
|
55
|
3,937
|
9 Enero 2012, 10:26
por Psyke1
|
|