/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

La serie más larga

 
      Índice del Foro elrincondelc.com -> Algoritmos
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
oldfox64



Registrado: 29 Jun 2008
Mensajes: 60
Ubicación: CAT

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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)

MensajePublicado: 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

MensajePublicado: 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)

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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
      Índice del Foro elrincondelc.com -> Algoritmos
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com