| Ver tema anterior :: Ver siguiente tema | | Autor | Mensaje |
|---|
oldfox64

Registrado: 29 Jun 2008 Mensajes: 60 Ubicación: CAT
| Publicado: 05/02/2011 3:33 am | | | Título: La serie más larga |
| Buenas. En C. Tengo un programa, al que creo entender, pero no me funciona.
Entrada: Secuencia de enteros acabada en 0. Salida: La serie de enteros ordenada descendentemente más larga.
Ejemplo: 5 3 2 8 4 1 1 8 0 La serie más larga seria 8 4 1 1
Mi algoritmo:
| Código: | void tratar_t(int t1[], int &n1, int t2[], int &n2){ int i, j; if(n1>n2){ j=0; for(i=0; i<=n1; i++){ t1[i]=t2[j]; j++; } n2=j; } } |
n1 (previamente inicializado, n2 tambien) sale de aqui:
| Código: | void leer_e(int t[], int &n, int &e){ int i=0; while(t[i]<=e || e!=0){ t[i]=e; scanf("%d", &e); i++; } n=i; //longitud de la serie } |
Lo que hago es copiar la serie más larga de t1 en t2. Comparo hasta que la secuencia llegue a 0. La salida será t2. El problema es que n2 me sale siempre 0. Si creeis que el algoritmo está bien, entonces postearé el programa entero para ver si el problema está en otra parte.
Un saludo. _________________ "Construir el futuro y preservar el pasado, es lo mismo" - S.S |
| | Volver arriba | |  | polly
Registrado: 19 Jul 2007 Mensajes: 602
| Publicado: 05/02/2011 7:16 am | | | Título: |
| Tienes un error muy gordo en la sintaxis. En la definicion de tus funciones pones un ampersand '&' en el paso de parametros. Supongo que querras que se pasen por referencia, si ese es el caso tienes que cambiarlos por '*'.
S2 |
| | Volver arriba | |  | polly
Registrado: 19 Jul 2007 Mensajes: 602
| Publicado: 05/02/2011 8:12 am | | | Título: |
| Por si te interesa:
| Código: | void secuencia(int v[], int len, int *inicio, int *tam) {
int i; int inicio_tmp = 0; int k = 0; int t_tmp = 1; /* tamano temporal de la secuencia */
for (i = 1; i < len-1; i++, k++) { if (v[k] >= v[i]) { /* Orden descendente */ inicio_tmp = i - t_tmp; /* Marcar el inicio de la secuancia mas larga hasta el momento */ t_tmp++; /* Marcar el tamano de la secuencia mas larga hasta el momento */ } else { if (t_tmp >= *tam) { /* Ver si la secuencia es la mas larga de todas */ *tam = t_tmp; t_tmp = 1; /* Reestablecer el tam temporal a 1 para seguir buscando mas secuencias */ *inicio = inicio_tmp; /* Marcar el inicio de la secuencia mas larga hasta el momento */ } } } }
|
El algoritmo recibe el vector de numeros 'v', su tamaño 'len', y devuelve el inicio de la secuencia mas larga (siguiendo tus restricciones) y su tamaño. Basicamente lo que hace es comparar un elemento con el siguiente e ir verificando el orden descendente y si el tamaño es el maximo hasta ese momento.
Una prueba:
| Código: | #include <stdio.h> #define N 9 int main() {
int v[N] = {5, 3, 2, 8, 4, 1, 1, 8, 0}; int inicio, longitud;
longitud = 1; /* Por defecto la secuencia mas larga es 1 */ secuencia(v, 9, &inicio, &longitud);
printf("La sec mas larga empieza en %d y su tamano es %d\n", inicio, longitud); /* Contando desde cero */
return 0; }
|
Creo que funciona bien, no lo he revisado a fondo, tan solo con un par de simulaciones.
S2 |
| | Volver arriba | |  | | rir3760

Registrado: 01 Oct 2004 Mensajes: 6586 Ubicación: Mexico
| Publicado: 05/02/2011 9:23 am | | | Título: |
| Una forma ligeramente distinta sin utilizar una funcion:
| Código: | #include <stdio.h> #include <stdlib.h>
int main(void) { int elem[] = {5, 3, 2, 8, 4, 1, 1, 8, 0}; int num_elem = (int) (sizeof elem / sizeof elem[0]); int i; int j; int inicio; int fin; inicio = fin = i = 0; for (j = 1; j < num_elem; j++) if (elem[j] > elem[j - 1]){ if ((j - i) > (fin - inicio)){ inicio = i; fin = j; } i = j; } for (i = inicio; i < fin; i++) printf(" %d", elem[i]); putchar('\n'); return EXIT_SUCCESS; } |
Un saludo _________________ Memory never recaptures reality. Memory reconstructs. All reconstructions change the original, becoming external frames of reference that inevitably fall short. -- Mentat Handbook |
| | Volver arriba | |  | polly
Registrado: 19 Jul 2007 Mensajes: 602
| Publicado: 05/02/2011 10:01 am | | | Título: |
| Me acabo de dar cuenta de que mi solucion y la de rir3760 fallan con secuencias como estas:
{4, 5, 6, 7, 8, 9, 10, 9, 0}; {1,1,1,1,1,1,1,1,0};
He modificado mi funcion y ahora parece que funciona en los casos anteriores:
| Código: | void secuencia(int v[], int len, int *inicio, int *tam) {
int i; int inicio_tmp = 0; int k = 0; int t_tmp = 1; /* tamano temporal de la secuencia */ *inicio = 0; for (i = 1; i < len-1; i++, k++) { if (v[k] >= v[i]) { /* Orden descendente */ inicio_tmp = i - t_tmp; /* Marcar el inicio de la secuancia mas larga hasta el momento */ t_tmp++; /* Marcar el tamano de la secuencia mas larga hasta el momento */ } else { if (t_tmp >= *tam) { /* Ver si la secuencia es la mas larga de todas */ *tam = t_tmp; t_tmp = 1; /* Reestablecer el tam temporal a 1 para seguir buscando mas secuencias */ *inicio = inicio_tmp; /* Marcar el inicio de la secuencia mas larga hasta el momento */ } } } *inicio = inicio_tmp; if (t_tmp != 1) *tam = t_tmp; }
|
S2 |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 6586 Ubicación: Mexico
| Publicado: 05/02/2011 4:16 pm | | | Título: |
| En mi caso el error se debe al ultimo elemento, al ser este menor que cualquier otro elemento sera tomado (sin serlo) como parte de la secuencia.
Ya que ese valor es el terminador se puede solucionar sustituyendolo con un sentinela (bajo el supuesto de que la entrada no contendra el valor maximo para el tipo signed int):
| Código: | #include <stdio.h> #include <stdlib.h> #include <limits.h>
int main(void) { int elem[] = {4, 5, 6, 7, 8, 9, 10, 9, INT_MAX}; int num_elem = (int) (sizeof elem / sizeof elem[0]); int i; int j; int inicio; int fin; inicio = fin = i = 0; for (j = 1; j < num_elem; j++) if (elem[j] > elem[j - 1]){ if ((j - i) > (fin - inicio)){ inicio = i; fin = j; } i = j; } for (i = inicio; i < fin; i++) printf(" %d", elem[i]); putchar('\n'); return EXIT_SUCCESS; } |
Un saludo _________________ Memory never recaptures reality. Memory reconstructs. All reconstructions change the original, becoming external frames of reference that inevitably fall short. -- Mentat Handbook |
| | Volver arriba | |  | | cheroky
Registrado: 22 Sep 2005 Mensajes: 2479 Ubicación: Valladolid (España)
| Publicado: 06/02/2011 9:56 am | | | Título: |
| Hola.
Una versión con punteros. Imprime la sucesión descendente más larga. Si dos o más sucesiones son de igual longitud se imprime la ultima:
| Código: | int main(void) { int v[] = {1, 6, 4, 3, 2, 2, 12, 9, 8, 0}; int *pa, *pb, *r, *k;
pa = r = k = v - 1; for(pb = v; *pb; pb++) if(pb[0] < pb[1] || !pb[1]) if(pb - pa > k - r) r = pa + 1, k = pa = pb; for(; r <= k; r++) printf("%d ", *r); return 0; } |
·?0ƒ· _________________ La cuestión no es si hay vida inteligente en otros planetas lejanos. La cuestión es si hay vida inteligente aquí. |
| | Volver arriba | |  | oldfox64

Registrado: 29 Jun 2008 Mensajes: 60 Ubicación: CAT
| Publicado: 07/02/2011 10:04 am | | | Título: |
| Bueno, a ver, olvidemonos de las acciones/funciones. He aquí todo el programa en funcion main:
| Código: | #include <stdio.h> #define M 100 int main(){ int t1[M], t2[M]; int n1=0, n2=0; //n1 = long. serie actual, n2 = long. serie más larga int x; //lector int i,j; printf("Intro. serie de enters acabada en 0:\n"); //inicializacion scanf("%d", &x); i=0; while(t1[i]<=x || x!=0){ t1[i]=x; scanf("%d", &x); i++; } n1=i; //tratamiento while(x!=0){ if(n1>n2){ j=0; for(i=0; i<=n1; i++){ t1[i]=t2[j]; j++; } n2=j; } scanf("%d", &x); i=0; n1=0; while(t1[i]<=x || x!=0){ t1[i]=x; scanf("%d", &x); i++; } n1=i; } //resultado printf("\nSerie mes larga: %d\n", n2); for(i=0; i<n2; i++) printf("%d ", t2[i]); putchar('\n');
system("pause"); return 0; }
|
Vuestros códigos estan muy bien, pero necesito saber qué es lo que yo tengo mal y como podria rreglarlo :S
Lo que no hago bien es copiar t1 en t2, algo que en principio tendria que ser facilísimo, pero no entiendo porque no funciona. _________________ "Construir el futuro y preservar el pasado, es lo mismo" - S.S |
| | Volver arriba | |  | cheroky
Registrado: 22 Sep 2005 Mensajes: 2479 Ubicación: Valladolid (España)
| Publicado: 07/02/2011 10:23 am | | | Título: |
| Hola oldfox64, tienes razón. En mi caso he preferido hacer una implementación nueva por que no dispongo de tiempo ni para mear y tardo menos que en depurar o revisar lo escrito por terceros.
Espero que algún compañero pueda ayudarte.
PD: Reconfigura tu editor o ide para que en lugar de usar tabulaciones útilice espacios en blanco.
·?0ƒ· _________________ La cuestión no es si hay vida inteligente en otros planetas lejanos. La cuestión es si hay vida inteligente aquí. |
| | Volver arriba | |  | | polly
Registrado: 19 Jul 2007 Mensajes: 602
| Publicado: 07/02/2011 12:07 pm | | | Título: |
| Yo creo que lo que tienes mal es la captura de datos. Por ejemplo, en el primer 'while' tienes 't1[i]<=x' pero 't1' no tiene aun valores y por tanto 't1[i]' no tiene asignado ningun valor.
Despues, supongo que el primer bucle while es para la captura de datos. Entonces no veo sentido al segundo scanf() dentro del 2º while.
S2 |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 6586 Ubicación: Mexico
| Publicado: 07/02/2011 3:37 pm | | | Título: |
| Como ya comento polly estas mesclando la lectura de datos con el proceso y, para serte honesto, no entiendo que tratas de hacer con las variables temporales y utilizando dos arrays (no es necesario la copia de las series).
Y antes de utilizar la funcion system debes tener acceso a su prototipo, eso se consigue (la forma usual) incluyendo el encabezado <stdlib.h>.
Una vez corregida y reducida la parte sobre la lectura de datos tu programa quedaria asi:
| Código: | #include <stdio.h> #include <stdlib.h>
#define NUM_ELEM 100
int main(void) {
int num[NUM_ELEM]; int i; /* Lectura de los numeros */ puts("Indica la serie de valores (0 para terminar)"); i = 0; while (i < NUM_ELEM && scanf("%d", num + i) == 1 && num[i] != 0) i++; /* Procesamiento de los numeros */ system("pause"); return EXIT_SUCCESS; } |
Falta agregar la logica (a tu estilo, por supuesto) para reconocer la secuencia mas larga.
Un saludo _________________ Memory never recaptures reality. Memory reconstructs. All reconstructions change the original, becoming external frames of reference that inevitably fall short. -- Mentat Handbook |
| | Volver arriba | |  | | |
| No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas
|
|
| |