Ayuda con ejercicio de matrices transpuestas y simetricas

Iniciado por dato000, 18 Diciembre 2013, 02:58 AM

0 Miembros y 1 Visitante están viendo este tema.

dato000

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:


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:


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 (cpp) [Seleccionar]

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <time.h>

using namespace std;

void generarNumeros(int **matriz, int tam)
{
    //Generando nçumeros aleatorios con indexación
    /*for (int i =0; i < tam; i++)
    {
        for(int j=0; j < tam; j++)
        {
            matriz[i][j] = 1 + rand() % 19;
        }
    }*/

    //Generando nçumeros aleatorios con aritmetica de punteros
    for (int i=0; i < tam; i++ )
    {
        for(int j=0; j < tam; j++)
        {
            *(*(matriz+i)+j) = 1 + rand() % 19;
        }
    }
}

void imprimirMatriz(int **matriz, int tam)
{
    // Imprimiendo por indexación
    /*for (int i =0; i < tam; i++)
    {
        for(int j=0; j < tam; j++)
        {
            cout << matriz[i][j];
            cout << "   ";
        }
        cout << endl;
    }*/

    // Imprimiendo por aritmetica de punteros
    for (int i=0; i < tam; i++ )
    {
        for(int j=0; j < tam; j++)
        {
            cout << *(*(matriz+i)+j);
            cout << "   ";
        }
        cout << endl;
    }
}

void transpuesta(int **matriz, int tam)
{
    int aux;
    for (int i=0; i < tam; i++ )
    {
        for(int j=0; j < tam; j++)
        {
            if(i == j)
            {
                aux = *(*(matriz+i)+j);
                *(*(matriz+i)+j) = *(*(matriz+j)+i);
                *(*(matriz+j)+i) = aux;
            }
        }
    }
}

int main()
{
    srand(time(0));
    int tamanyo;
    int **matrizPrincipal; // puntero para dos dimensiones del arreglo

    cout << "Problema 11.2 ----_____----" << endl << endl;
    cout << "Ingrese el tamaño de la matriz:  "; cin >> tamanyo;

    matrizPrincipal = new int*[tamanyo]; /*asignacion de memoria de n punteros a enteros*/

    for (int i =0; i < tamanyo; i++)
        matrizPrincipal[i] = new int[tamanyo]; /*asignacion de memoria para cada entero*/

    /*comprobar si fue creado */
    if (matrizPrincipal == NULL)
    {
        cout << "No se pudo crear la matriz" << endl;

    }

    generarNumeros(matrizPrincipal, tamanyo);
    imprimirMatriz(matrizPrincipal, tamanyo);
    cout << endl << endl;

    // matriz transpuesta
    cout << endl << "***MATRIZ TRANSPUESTA***" << endl;
    transpuesta(matrizPrincipal, tamanyo);
    imprimirMatriz(matrizPrincipal, tamanyo);


    return 0;
}



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  ;-) ;-)



leosansan

#1
Si lo piensa más despacio seguro lo sacas sin problemas. Por si acaso te paso la función transponer corregida:

Código (cpp) [Seleccionar]

void transpuesta(int **matriz, int tam)
{
   int aux;
   for (int i=0; i < tam; i++ )
   {
       for(int j=0; j < tam && j<i;j++)
       {
           {
               aux = *(*(matriz+i)+j);
               *(*(matriz+i)+j) = *(*(matriz+j)+i);
               *(*(matriz+j)+i) = aux;
           }
       }
   }
}


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! ..... !!!!        

dato000

Cita de: leosansan en 18 Diciembre 2013, 07:16 AM
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

Cita de: leosansan en 18 Diciembre 2013, 07:16 AM
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.


Cita de: leosansan en 18 Diciembre 2013, 07:16 AM
Por cierto, ¿no te falta un delete al final del main?.
[/size]
Saluditos! ..... !!!!        

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 (cpp) [Seleccionar]

    delete[] matrizPrincipal; // liberando memoria de la matriz


es así verdad como se hace cierto??

Muchas gracias.



leosansan

#3
De nada, encantado de poder ayudar a un colega como tú.



Saluditos! ..... !!!!        

rir3760

Cita de: dato000 en 18 Diciembre 2013, 17:51 PMEs 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 (cpp) [Seleccionar]
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 (cpp) [Seleccionar]
for (int i = 0; i != tamanyo; ++i)
   delete[] matrizPrincipal[i];
delete[] matrizPrincipal;


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

dato000

Cita de: rir3760 en 18 Diciembre 2013, 18:04 PM
Primero debes liberar la memoria de cada fila y a continuación la memoria del bloque principal:
Código (cpp) [Seleccionar]
for (int i = 0; i != tamanyo; ++i)
   delete[] matrizPrincipal[i];
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 (cpp) [Seleccionar]


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <time.h>

using namespace std;

void generarNumeros(int **matriz, int tam)
{
    //Generando numeros aleatorios con indexacion
    /*for (int i =0; i < tam; i++)
    {
        for(int j=0; j < tam; j++)
        {
            matriz[i][j] = 1 + rand() % 19;
        }
    }*/

    //Generando numeros aleatorios con aritmetica de punteros
    for (int i=0; i < tam; i++ )
    {
        for(int j=0; j < tam; j++)
        {
            *(*(matriz+i)+j) = 1 + rand() % 19;
        }
    }
}

void imprimirMatriz(int **matriz, int tam)
{
    // Imprimiendo por indexacion
    /*for (int i =0; i < tam; i++)
    {
        for(int j=0; j < tam; j++)
        {
            cout << matriz[i][j];
            cout << "   ";
        }
        cout << endl;
    }*/

    // Imprimiendo por aritmetica de punteros
    for (int i=0; i < tam; i++ )
    {
        for(int j=0; j < tam; j++)
        {
            cout << *(*(matriz+i)+j);
            cout << "   ";
        }
        cout << endl;
    }
}

void transpuesta(int **matriz, int tam)
{
    int aux;
    for (int i=0; i < tam; i++ )
    {
        for(int j=0; j < tam   &&  j < i; j++)
        {
            aux = *(*(matriz+i)+j);
            *(*(matriz+i)+j) = *(*(matriz+j)+i);
            *(*(matriz+j)+i) = aux;

        }
    }
}

bool simetrica(int **matriz, int tam)
{
    for (int i=0; i < tam; i++ )
    {
        for(int j=0; j < tam   &&  j < i; j++)
        {
            if( !( *(*(matriz+i)+j) == *(*(matriz+j)+i) ) )
                return false;
        }
    }
    return true;
}

int main()
{
    srand(time(0));
    int tamanyo;
    int **matrizPrincipal; // puntero para dos dimensiones del arreglo

    cout << "Problema 11.2 ----_____----" << endl << endl;
    cout << "Ingrese el tamaño de la matriz:  "; cin >> tamanyo;

    matrizPrincipal = new int*[tamanyo]; /*asignacion de memoria de n punteros a enteros*/

    for (int i =0; i < tamanyo; i++)
        matrizPrincipal[i] = new int[tamanyo]; /*asignacion de memoria para cada entero*/

    /*comprobar si fue creado */
    if (matrizPrincipal == NULL)
    {
        cout << "No se pudo crear la matriz" << endl;

    }

    generarNumeros(matrizPrincipal, tamanyo);
    imprimirMatriz(matrizPrincipal, tamanyo);
    cout << endl << endl;

    // matriz transpuesta
    cout << endl << "***MATRIZ TRANSPUESTA***" << endl;
    transpuesta(matrizPrincipal, tamanyo);
    imprimirMatriz(matrizPrincipal, tamanyo);
    cout << endl << endl;

    // comprobando matriz simetrica
    if( simetrica(matrizPrincipal, tamanyo) )
    {
        cout << "La matriz SI es simetrica";
    }
    else
    {
        cout << "La matriz NO es simetrica";
    }

    cout << endl << endl << "ADIOS!!" << endl <<  endl;
    // Liberando memoria de la matriz
    for (int i = 0; i != tamanyo; ++i)
        delete[] matrizPrincipal[i];

    delete[] matrizPrincipal;

    return 0;
}