Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: dato000 en 18 Diciembre 2013, 02:58 am



Título: Ayuda con ejercicio de matrices transpuestas y simetricas
Publicado por: dato000 en 18 Diciembre 2013, 02:58 am
Buenas amigos, mi problema es el siguiente, se supone que debo hacer una matriz simetrica, y pues lo primero es realizar es una matriz transpuesta porque pues, de eso se trata aprender no??  ;-) ;-) verán, en el ejercicio me dicen que use indexación y aritmetica de apuntadores, para no alargar mucho el tema, dejo el enunciado:

Citar
Escribir un programa que encuentre una matriz de números reales simétrica. Para ello una función entera con entrada a la matriz determinará si ésta es simétrica. En otra función se generará la matriz con números aleatorios de 1 a 19.

Utilizar aritmética de apuntadores en la primera función; en la segunda, indexación.

En el ejercicio, pues como verán, lo hice de las dos formas, no de sobrado, sino por saber como trabajan por separado. Y pues mi problema no nisiquiera de programación, sino que no he podido dar con el chiste de hacer una maldita matriz transpuesta, cambiando de lugar los elementos de la matriz para que luego deba hacer la comprobación de si existe o no una matriz simétrica.

Para que me entiendan dejo el ejemplo de una matriz transpuesta:

(http://www.vitutor.org/algebra/matrices/images/10_0.gif)

Donde se puede ver, que los elementos de las filas y las columnas quedan "transpuestos" unos con otros, menos la diagonal principal, cambiando de lugar, la simetria se da cuando después del cambio los valores númericos de los elementos siguen siendo los mismos, de esta forma:

(http://www.psico.uniovi.es/Dpto_Psicologia../metodos/tutor.3/mat4.gif)

Y pues mi problema radica en que no he podido hacer la transposición, ya trate de varias maneras, pero me falla la lógica, no he podido dar con el chiste, me dan una mano amig@s???

he aquí el código, no es nada complicado:

Código
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <time.h>
  5.  
  6. using namespace std;
  7.  
  8. void generarNumeros(int **matriz, int tam)
  9. {
  10.    //Generando nçumeros aleatorios con indexación
  11.    /*for (int i =0; i < tam; i++)
  12.     {
  13.         for(int j=0; j < tam; j++)
  14.         {
  15.             matriz[i][j] = 1 + rand() % 19;
  16.         }
  17.     }*/
  18.  
  19.    //Generando nçumeros aleatorios con aritmetica de punteros
  20.    for (int i=0; i < tam; i++ )
  21.    {
  22.        for(int j=0; j < tam; j++)
  23.        {
  24.            *(*(matriz+i)+j) = 1 + rand() % 19;
  25.        }
  26.    }
  27. }
  28.  
  29. void imprimirMatriz(int **matriz, int tam)
  30. {
  31.    // Imprimiendo por indexación
  32.    /*for (int i =0; i < tam; i++)
  33.     {
  34.         for(int j=0; j < tam; j++)
  35.         {
  36.             cout << matriz[i][j];
  37.             cout << "   ";
  38.         }
  39.         cout << endl;
  40.     }*/
  41.  
  42.    // Imprimiendo por aritmetica de punteros
  43.    for (int i=0; i < tam; i++ )
  44.    {
  45.        for(int j=0; j < tam; j++)
  46.        {
  47.            cout << *(*(matriz+i)+j);
  48.            cout << "   ";
  49.        }
  50.        cout << endl;
  51.    }
  52. }
  53.  
  54. void transpuesta(int **matriz, int tam)
  55. {
  56.    int aux;
  57.    for (int i=0; i < tam; i++ )
  58.    {
  59.        for(int j=0; j < tam; j++)
  60.        {
  61.            if(i == j)
  62.            {
  63.                aux = *(*(matriz+i)+j);
  64.                *(*(matriz+i)+j) = *(*(matriz+j)+i);
  65.                *(*(matriz+j)+i) = aux;
  66.            }
  67.        }
  68.    }
  69. }
  70.  
  71. int main()
  72. {
  73.    srand(time(0));
  74.    int tamanyo;
  75.    int **matrizPrincipal; // puntero para dos dimensiones del arreglo
  76.  
  77.    cout << "Problema 11.2 ----_____----" << endl << endl;
  78.    cout << "Ingrese el tamaño de la matriz:  "; cin >> tamanyo;
  79.  
  80.    matrizPrincipal = new int*[tamanyo]; /*asignacion de memoria de n punteros a enteros*/
  81.  
  82.    for (int i =0; i < tamanyo; i++)
  83.        matrizPrincipal[i] = new int[tamanyo]; /*asignacion de memoria para cada entero*/
  84.  
  85.    /*comprobar si fue creado */
  86.    if (matrizPrincipal == NULL)
  87.    {
  88.        cout << "No se pudo crear la matriz" << endl;
  89.  
  90.    }
  91.  
  92.    generarNumeros(matrizPrincipal, tamanyo);
  93.    imprimirMatriz(matrizPrincipal, tamanyo);
  94.    cout << endl << endl;
  95.  
  96.    // matriz transpuesta
  97.    cout << endl << "***MATRIZ TRANSPUESTA***" << endl;
  98.    transpuesta(matrizPrincipal, tamanyo);
  99.    imprimirMatriz(matrizPrincipal, tamanyo);
  100.  
  101.  
  102.    return 0;
  103. }
  104.  
  105.  

Si ven las librerias adicionales como "cstdio" o "cstdlib" era porque estaba probando el tipico caso de printf vs cout. Aunque creo que srand() debe funcionar con cstdlib...en fin, no da problemas de compilación, el problema esta en la función "transpuesta(int **matriz, int tam)", pues no he podido dar con el truco de transponer los elementos.

Les agradezco el interés y la ayuda, slsd  ;-) ;-)


Título: Re: Ayuda con ejercicio de matrices transpuestas y simetricas
Publicado por: leosansan en 18 Diciembre 2013, 07:16 am
Si lo piensa más despacio seguro lo sacas sin problemas. Por si acaso te paso la función transponer corregida:

Código
  1. void transpuesta(int **matriz, int tam)
  2. {
  3.    int aux;
  4.    for (int i=0; i < tam; i++ )
  5.    {
  6.        for(int j=0; j < tam && j<i;j++)
  7.        {
  8.            {
  9.                aux = *(*(matriz+i)+j);
  10.                *(*(matriz+i)+j) = *(*(matriz+j)+i);
  11.                *(*(matriz+j)+i) = aux;
  12.            }
  13.        }
  14.    }
  15. }
  16.  

Tenias dos fallos lógicos, por un lado sólo aplicabas los cambios a la diagonal- i==j- con lo que no cambia nada-, y por otro lado al recorrer  la matriz al completo, lo que haces en una mitad lo deshaces en la siguiente mitad. Por cierto, ¿no te falta un delete al final del main?.

Saluditos! ..... !!!!        (http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Ayuda con ejercicio de matrices transpuestas y simetricas
Publicado por: dato000 en 18 Diciembre 2013, 17:51 pm
Tenias dos fallos lógicos, por un lado sólo aplicabas los cambios a la diagonal- i==j- con lo que no cambia nada-,

Cierto, lo venia pensando ahora que regresaba a mi casa, lo que queria decir que es que fuera diferente a la diagonal i != j pero no cai en cuenta de ese minusculo descuido  :xD

y por otro lado al recorrer  la matriz al completo, lo que haces en una mitad lo deshaces en la siguiente mitad.
Ummmmm tienes razón, no pense en ese detalle, seguro que me hubiera atascado nuevamente con eso.


Por cierto, ¿no te falta un delete al final del main?.
[/size]
Saluditos! ..... !!!!        (http://st.forocoches.com/foro/images/smilies/aaaaa.gif)

Es que no habia llegado a ese punto porque me quede pensando en la función de la transpuesta. Pero luego de eso implemento correctamente el código.

Código
  1.    delete[] matrizPrincipal; // liberando memoria de la matriz
  2.  

es así verdad como se hace cierto??

Muchas gracias.


Título: Re: Ayuda con ejercicio de matrices transpuestas y simetricas
Publicado por: leosansan en 18 Diciembre 2013, 17:59 pm
De nada, encantado de poder ayudar a un colega como tú.



Saluditos! ..... !!!!        (http://st.forocoches.com/foro/images/smilies/aaaaa.gif)


Título: Re: Ayuda con ejercicio de matrices transpuestas y simetricas
Publicado por: rir3760 en 18 Diciembre 2013, 18:04 pm
Es que no habia llegado a ese punto porque me quede pensando en la función de la transpuesta. Pero luego de eso implemento correctamente el código.
Código
  1. delete[] matrizPrincipal; // liberando memoria de la matriz
es así verdad como se hace cierto??
Primero debes liberar la memoria de cada fila y a continuación la memoria del bloque principal:
Código
  1. for (int i = 0; i != tamanyo; ++i)
  2.   delete[] matrizPrincipal[i];
  3. delete[] matrizPrincipal;

Un saludo


Título: Re: Ayuda con ejercicio de matrices transpuestas y simetricas
Publicado por: dato000 en 18 Diciembre 2013, 18:42 pm
Primero debes liberar la memoria de cada fila y a continuación la memoria del bloque principal:
Código
  1. for (int i = 0; i != tamanyo; ++i)
  2.   delete[] matrizPrincipal[i];
  3. delete[] matrizPrincipal;

Un saludo

Ok, vale muchas gracias, me queda claro entonces, ya lo implemente, dejo el código completo por si tal vez un futuro (usando google o duckduckgo o pues alguien que tenga la tarea y use cualquier buscador) alguien lo necesita.


Código
  1.  
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <time.h>
  6.  
  7. using namespace std;
  8.  
  9. void generarNumeros(int **matriz, int tam)
  10. {
  11.    //Generando numeros aleatorios con indexacion
  12.    /*for (int i =0; i < tam; i++)
  13.     {
  14.         for(int j=0; j < tam; j++)
  15.         {
  16.             matriz[i][j] = 1 + rand() % 19;
  17.         }
  18.     }*/
  19.  
  20.    //Generando numeros aleatorios con aritmetica de punteros
  21.    for (int i=0; i < tam; i++ )
  22.    {
  23.        for(int j=0; j < tam; j++)
  24.        {
  25.            *(*(matriz+i)+j) = 1 + rand() % 19;
  26.        }
  27.    }
  28. }
  29.  
  30. void imprimirMatriz(int **matriz, int tam)
  31. {
  32.    // Imprimiendo por indexacion
  33.    /*for (int i =0; i < tam; i++)
  34.     {
  35.         for(int j=0; j < tam; j++)
  36.         {
  37.             cout << matriz[i][j];
  38.             cout << "   ";
  39.         }
  40.         cout << endl;
  41.     }*/
  42.  
  43.    // Imprimiendo por aritmetica de punteros
  44.    for (int i=0; i < tam; i++ )
  45.    {
  46.        for(int j=0; j < tam; j++)
  47.        {
  48.            cout << *(*(matriz+i)+j);
  49.            cout << "   ";
  50.        }
  51.        cout << endl;
  52.    }
  53. }
  54.  
  55. void transpuesta(int **matriz, int tam)
  56. {
  57.    int aux;
  58.    for (int i=0; i < tam; i++ )
  59.    {
  60.        for(int j=0; j < tam   &&  j < i; j++)
  61.        {
  62.            aux = *(*(matriz+i)+j);
  63.            *(*(matriz+i)+j) = *(*(matriz+j)+i);
  64.            *(*(matriz+j)+i) = aux;
  65.  
  66.        }
  67.    }
  68. }
  69.  
  70. bool simetrica(int **matriz, int tam)
  71. {
  72.    for (int i=0; i < tam; i++ )
  73.    {
  74.        for(int j=0; j < tam   &&  j < i; j++)
  75.        {
  76.            if( !( *(*(matriz+i)+j) == *(*(matriz+j)+i) ) )
  77.                return false;
  78.        }
  79.    }
  80.    return true;
  81. }
  82.  
  83. int main()
  84. {
  85.    srand(time(0));
  86.    int tamanyo;
  87.    int **matrizPrincipal; // puntero para dos dimensiones del arreglo
  88.  
  89.    cout << "Problema 11.2 ----_____----" << endl << endl;
  90.    cout << "Ingrese el tamaño de la matriz:  "; cin >> tamanyo;
  91.  
  92.    matrizPrincipal = new int*[tamanyo]; /*asignacion de memoria de n punteros a enteros*/
  93.  
  94.    for (int i =0; i < tamanyo; i++)
  95.        matrizPrincipal[i] = new int[tamanyo]; /*asignacion de memoria para cada entero*/
  96.  
  97.    /*comprobar si fue creado */
  98.    if (matrizPrincipal == NULL)
  99.    {
  100.        cout << "No se pudo crear la matriz" << endl;
  101.  
  102.    }
  103.  
  104.    generarNumeros(matrizPrincipal, tamanyo);
  105.    imprimirMatriz(matrizPrincipal, tamanyo);
  106.    cout << endl << endl;
  107.  
  108.    // matriz transpuesta
  109.    cout << endl << "***MATRIZ TRANSPUESTA***" << endl;
  110.    transpuesta(matrizPrincipal, tamanyo);
  111.    imprimirMatriz(matrizPrincipal, tamanyo);
  112.    cout << endl << endl;
  113.  
  114.    // comprobando matriz simetrica
  115.    if( simetrica(matrizPrincipal, tamanyo) )
  116.    {
  117.        cout << "La matriz SI es simetrica";
  118.    }
  119.    else
  120.    {
  121.        cout << "La matriz NO es simetrica";
  122.    }
  123.  
  124.    cout << endl << endl << "ADIOS!!" << endl <<  endl;
  125.    // Liberando memoria de la matriz
  126.    for (int i = 0; i != tamanyo; ++i)
  127.        delete[] matrizPrincipal[i];
  128.  
  129.    delete[] matrizPrincipal;
  130.  
  131.    return 0;
  132. }
  133.  
  134.