[C con Clase] Ayuda con la salida de la matriz final.

Ali Rincon alrincon1963 en hotmail.com
Vie Ene 3 22:55:16 CET 2014




El pasado 2014-01-03 18:22:52, Steven Davidson escribió:
 
SD> Hola Ali,
SD> 2014/1/1 Ali Rincon <alrincon1963 en hotmail.com>
SD> > Holq Steven, gracias nuevamente por tu gentileza en responderme. Resolví
SD> > mi problema y era simplemente que había olvidado una instrucción simple y
SD> > que la había pasado por alto. Con introducir printf("\n") la matriz final
SD> > reducida sale correctamente en la parte de mostrar matriz final. Ahora con
SD> > relación a lo que dices, es cierto, existe una inconsistencia cuando k=9,
SD> > Sin embargo, si introduzco indices--; antes del primer bucle for, que es
SD> > para leer las filas, el programa arroja un resultado incorrecto.
SD> > Simplemente se lo coloque a la condición del primer bucle for( k=posición;
SD> > k<indices-1; k++ ), y listo el programa corre y es mas consistente.
SD> >
SD> > Ahora, deseo pedirte, si puedes ayudarme en una complicación adicional al
SD> > código anterior. Ahora tengo la misma matriz anterior 10x10, pero el numero
SD> > 1 (por ejemplo), se repite varias veces en diferentes filas y se desea
SD> > eliminar nuevamente dichas filas. Obviamente la dimensionalidad de la
SD> > matriz resultante es importante, pero en el caso general ésta no se sabe.
SD> > Aquí si, pues estamos tratando con una matriz simple 10x10. Aquí te envió
SD> > lo que hice, el programa corre y muestra la matriz final reducida para el
SD> > caso de un valor escogido (en este caso escogí el valor de 1), pero tengo
SD> > problemas con las filas, pues después de cada bucle for, la matriz se va
SD> > reduciendo y el programa lee esta ultima matriz y las filas donde aparece
SD> > el numero 1, no coinciden con la matriz original, obviamente. Mi problema
SD> > es como hago para corregir este fallo.
SD> >
SD> >
SD> - Hay dos soluciones:
SD> 1. Ajusta el valor mostrado que se desplaza según la cantidad de filas
SD> eliminadas. Siguiendo tu ejemplo, tenemos,
SD> El valor se encuentra en la fila: 0
SD> El valor se encuentra en la fila: 2
SD> El valor se encuentra en la fila: 6
SD> Cuando debería ser:
SD> El valor se encuentra en la fila: 0
SD> El valor se encuentra en la fila: 3
SD> El valor se encuentra en la fila: 8
SD> Podemos ajustar cada índice por el número de eliminaciones - guardado en
SD> 'contarfilas'; esto es,
SD> El valor se encuentra en la fila: 0 + 0
SD> El valor se encuentra en la fila: 2 + 1
SD> El valor se encuentra en la fila: 6 + 2
SD> En general,
SD> printf( "El valor se encuentra en la fila: %d\n", i + contarfilas );
SD> 2. En lugar de hacer la búsqueda y eliminación en la misma iteración,
SD> separamos las dos tareas. Esto implica que tenemos que guardar los índices
SD> para las filas a eliminar. Por ejemplo,
SD> int aFilasParaEliminar[10] = { 0 };
SD> ...
SD> // Buscar filas a eliminar
SD> contarFilas = 0;
SD> for( i=0; i<indices; i++ )
SD>   for( j=0; j<10; j++ )
SD>     if( matriz[i][j] == valor )
SD>     {
SD>       printf( "El valor se encuentra en la fila: %d\n", i );
SD>       aFilasParaEliminar[contarFilas++] = i;
SD>     }
SD> // Eliminar las filas encontradas
SD> ...
SD> - Deberías usar 'indices-contarFilas' si no eliges la segunda solución. No
SD> interesa rebasar la cantidad actual de filas en la matriz, porque
SD> estaríamos repitiendo la comprobación y posiblemente hallemos erróneamente
SD> una fila previamente eliminada al final de la matriz, que la queremos
SD> eliminar otra vez. Por ejemplo,
SD> 1   2   3   4   5   6   7   8   9   10
SD> ...
SD> 81  82  83  84  85  86  87   1  89  90
SD> 91  1   93  94  95  96  97  98  99 100
SD> Recuerda que al eliminar una fila, tu algoritmo realmente la eliminar
SD> mudando todas las otras filas a una fila anterior, por lo que obtendremos:
SD> ...
SD> 81  82  83  84  85  86  87   1  89  90
SD> 91  1   93  94  95  96  97  98  99 100
SD> 91  1   93  94  95  96  97  98  99 100
SD> Y luego, será:
SD> ...
SD> 91  1   93  94  95  96  97  98  99 100
SD> 91  1   93  94  95  96  97  98  99 100
SD> 91  1   93  94  95  96  97  98  99 100
SD> Aunque tu algoritmo no realice la copia, en este ejemplo sí indicará que ha
SD> encontrado otras dos filas a eliminar, cuando actualmente no deberían
SD> existir. Esto ocurre cuando se debe eliminar la última fila, porque durante
SD> el proceso de eliminación, sólo mudamos los datos, pero los datos de la
SD> última fila siguen existiendo. Por ello, debes procurar usar la cantidad
SD> actual. Como no quieres modificar 'indices', entonces tienes que reajustar
SD> la cantidad con el desplazamiento 'contarFilas'.
SD> Espero que esto te oriente.
SD> Steven
SD> _______________________________________________
SD> Lista de correo Cconclase Cconclase en listas.conclase.net
SD> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
SD> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ


Gracias nuevamente, Steven, por tu ayuda y orientación. Mira, realmente tienes razón con respecto a los indices, y concluyo que mi algoritmo no sirve para lo que pretendo. Me explico: Inicialmente el código funciona si pedimos eliminar las filas donde aparezca el numero 1 (tomado como ejemplo) de la matriz del fichero origen escrita como:

Introduzca el nombre del fichero origen: c:\matriz2.txt

   1   2   3   4   5   6   7   8   9  10

  11  12  13  14  15  16  17  18  19  20

  21  22  23  24  25  26  27  28  29  30

  31  32  33  34  35  36   1  38  39  40

  41  42  43  44  45  46  47  48  49  50

  51  52  53  54  55  56  57  58  59  60

  61  62  63  64  65  66  67  68  69  70

  71  72  73  74  75  76  77  78  79  80

  81  82  83  84  85  86  87   1  89  90

  91  92  93  94  95  96  97  98  99 100

Introduzca el numero cuya fila sera eliminada: 1
El valor se encuentra en la fila: 0
El valor se encuentra en la fila: 3
El valor se encuentra en la fila: 8
El numero de filas en que se encuentra el numero 1 son: 3
La matriz final sera:

  11  12  13  14  15  16  17  18  19  20

  21  22  23  24  25  26  27  28  29  30

  41  42  43  44  45  46  47  48  49  50

  51  52  53  54  55  56  57  58  59  60

  61  62  63  64  65  66  67  68  69  70

  71  72  73  74  75  76  77  78  79  80

  91  92  93  94  95  96  97  98  99 100


Process returned 0 (0x0)   execution time : 14.351 s
Press any key to continue.

En este caso el código funciona. Pero si modifico la matriz origen, como en este caso:

Introduzca el nombre del fichero origen: c:\matriz4.txt

   1   2   3   4   5   6   7   8   9  10

  11  12  13  14  15  16  17  18  19  20

  21  22  23  24  25  26  27  28  29  30

  31  32  33  34  35  36   1  38  39  40

  41  42  43  44  45  46  47  48  49  50

  51  52  53  54  55  56  57  58  59  60

  61  62  63  64  65  66  67  68  69  70

  71  72  73  74  75  76  77  78  79  80

  81  82  83  84  85  86  87   1  89  90

  91  92  93   1  95  96  97  98  99 100

Introduzca el numero cuya fila sera eliminada: 1
El valor se encuentra en la fila: 0
El valor se encuentra en la fila: 3
El valor se encuentra en la fila: 8
El valor se encuentra en la fila: 9
El numero de filas en que se encuentra el numero 1 son: 4
La matriz final sera:

  11  12  13  14  15  16  17  18  19  20

  21  22  23  24  25  26  27  28  29  30

  41  42  43  44  45  46  47  48  49  50

  51  52  53  54  55  56  57  58  59  60

  61  62  63  64  65  66  67  68  69  70

  71  72  73  74  75  76  77  78  79  80

  91  92  93   1  95  96  97  98  99 100


Process returned 0 (0x0)   execution time : 8.903 s
Press any key to continue.

el código no funciona. Y no funciona por la razón que tu dices. Al llegar a la ultima fila k=9, el programa no encuentra la fila k+1. Por esta razón lo que escribí no me sirve. Tu idea de almacenar las filas que me interesan eliminar (dado el valor por teclado) me parece muy buena. Yo había separado la tarea de búsqueda y eliminación, tal cual como a continuación te escribo:
.
.
.
//Imposicion de la condicion.

    printf("Introduzca el numero cuya fila sera eliminada: ");
    scanf("%d", &valor);

    contarfilas=0;
    for(i=0; i<indices; i++)
    {
        for(j=0; j<10; j++)
        {
            if(matriz[i][j] == valor)
            {
                printf("El valor se encuentra en la fila: %d", i);
                printf("\n");
                contarfilas=contarfilas+1;
            }
        }
    }
    printf("El numero de filas en que se encuentra el numero %d son: %d", valor, contarfilas);
    printf("\n");

    //Remover la fila donde se encuentre el valor introducido por teclado.

    contarfilas=0;
    for(i=0; i<indices; i++)
    {
        for(j=0; j<10; j++)
        {
            if(matriz[i][j] == valor)
            {
                //contarfilas=contarfilas+1;
                contarfilas++;
                posicion = i;

                for(k=posicion; k<(indices-contarfilas); k++)  //Con este bucle deberian retroceder las filas!!
                {
                   for(j=0; j<10; j++)
                   {
                       matriz[k][j] = matriz[k+1][j];
                   }
                }
            }
        }
    }
.
.
.
y no funciona, como te comente arriba. Por tanto, la segunda opcion de la que me hablas es la viable. Implementando parte de lo que dices, queda:

//Imposicion de la condicion.

    printf("Introduzca el numero cuya fila sera eliminada: ");
    scanf("%d", &valor);

    contarfilas=0;
    for(i=0; i<10; i++)
    {
        for(j=0; j<10; j++)
        {
            if(matriz[i][j] == valor)
            {
                printf("El valor se encuentra en la fila: %d", i);
                printf("\n");
                filasparaeliminar[contarfilas++]=i;
                //contarfilas=contarfilas+1;
            }
        }
    }
    printf("El numero de filas en que se encuentra el numero %d son: %d", valor, contarfilas);
    printf("\n");

    //Remover la fila donde se encuentre el valor introducido por teclado.

                                  (???)

y hasta aqui el codigo funciona bien:

Introduzca el nombre del fichero origen: c:\matriz4.txt

   1   2   3   4   5   6   7   8   9  10

  11  12  13  14  15  16  17  18  19  20

  21  22  23  24  25  26  27  28  29  30

  31  32  33  34  35  36   1  38  39  40

  41  42  43  44  45  46  47  48  49  50

  51  52  53  54  55  56  57  58  59  60

  61  62  63  64  65  66  67  68  69  70

  71  72  73  74  75  76  77  78  79  80

  81  82  83  84  85  86  87   1  89  90

  91  92  93   1  95  96  97  98  99 100

Introduzca el numero cuya fila sera eliminada: 1
El valor se encuentra en la fila: 0
El valor se encuentra en la fila: 3
El valor se encuentra en la fila: 8
El valor se encuentra en la fila: 9
El numero de filas en que se encuentra el numero 1 son: 4

Process returned 0 (0x0)   execution time : 11.567 s
Press any key to continue.

Honestamente, no se como copiar las filas que me interesan de una matriz dada, donde los indices se almacenan en el vector filasparaeliminar[10]. Me puedes dar una idea de como hacer esto, por favor??

Ali Rincon






Más información sobre la lista de distribución Cconclase