domingo, 10 de janeiro de 2010

Matrizes. Parte III (transposta/determinante)

Agora que já conhecemos as matrizes, vamos ver algumas operações com matrizes.

Transpondo uma matriz quadrada
Vamos começar criando uma matriz transposta de uma matriz quadrada 3x3. Não sabe o que é matriz transposta? Veja aqui.
Olhando a primeira vista podemos pensar que seria só trocar a posição dos elementos. Algo que o fragmento de código abaixo faria sem problemas.


 for(i = 0; i < colunas; i++)
    for(j = 0; j < colunas; j++){
       aux = mat[i][j];
       mat[i][j] = mat[j][i];
       mat[j][i] = aux;
 }


Se você tiver a curiosidade pode implementar este código. E vai ter uma triste surpresa (rsrs).
Será que você pode dizer por que este código não funciona?

Como você já descobriu, este código funciona (compila e executa), mas não faz o que se esperava que fizesse. Na verdade, ele troca a posição dos elementos do vetor e, depois, os retorna para as posições iniciais. Ele não sabe quando os elementos não precisam ser trocados, ou porque já foram, ou porque realmente não é necessário, como é o caso dos elementos da diagonal principal da matriz.
No caso da diagonal principal é fácil, basta saber se o número da coluna é igual ao da linha. E no outros casos? Como evitar que a troca seja feita novamente, fazendo o elemento voltar para a sua posição inicial?
Vamos fazer um teste de mesa (ou chinês, como preferirem) e ver como as trocas são feitas.
Linha = 0, Coluna = 0 => Diagonal principal, não precisa trocar;
Linha = 0, Coluna = 1 => Troca o elemento com o da Linha = 1, Coluna = 0;
Linha = 0, Coluna = 2 => Troca o elemento com o da Linha = 2, Coluna = 0;

Linha = 1, Coluna = 0 => A troca já foi feita, não precisa trocar;
Linha = 1, Coluna = 1 => Diagonal principal, não precisa trocar;
Linha = 1, Coluna = 2 => Troca o elemento com o da Linha = 2, Coluna = 1;
Linha = 2, Coluna = 0 => A troca já foi feita, não precisa trocar;
Linha = 2, Coluna = 1 => A troca já foi feita, não precisa trocar;
Linha = 2, Coluna = 2 => Diagonal principal, não precisa trocar;

Observando as linhas em negrito, que mostram as trocas que precisam ser realmente feitas, podemos encontrar algo em comum entre elas. Já percebeu?

O número da linha é menor que o da coluna! Agora ficou fácil, né?
Veja abaixo como fica o código completo que faz a transposição de uma matriz quadradra 3x3.


#include <stdio.h>
#include <stdlib.h>
 
const int LINHAS = 3;
const int COLUNAS = 3;
 
void preenche_mat_int(int [][3]);
void exibe_mat_int(int [][3]);
void transpor_mat_int(int [][3]);
 
int main(){
 int matriz[3][3];
 
 preenche_mat_int(matriz);
 exibe_mat_int(matriz);
 transpor_mat_int(matriz);
 exibe_mat_int(matriz);
 system("pause");
}
 
int ler_int(){
 int digitado;
 
 printf("Digite um valor inteiro: ");
 scanf("%d",&digitado);
 return digitado;
}
 
void mostra_int(int num){
 printf("%d ",num);
}
 
void preenche_mat_int(int mat[][3]){
 int i, j;
 
 printf("\nPREENCHENDO A MATRIZ:\n");
 for(i = 0; i < LINHAS; i++)
    for(j = 0; j < COLUNAS; j++)
       mat[i][j] = ler_int();
}
 
void exibe_mat_int(int mat[][3]){
 int i, j;
 
 printf("\n");
 for(i = 0; i < LINHAS; i++){
    for(j = 0; j < COLUNAS; j++)
       mostra_int(mat[i][j]);
    printf("\n");
 }
 printf("\n\n");
}
 
void transpor_mat_int(int mat [][3]){
 int i, j, aux;
 
 printf("\nTRANSPOSICAO DA MATRIZ:\n");
 for(i = 0; i < LINHAS; i++)
    for(j = 0; j < COLUNAS; j++)
       if((i != j) && (i < j)){
          aux = mat[i][j];
          mat[i][j] = mat[j][i];
          mat[j][i] = aux;
       }
}


Determinante de uma matriz quadrada 2x2
Outra função comum no trabalho com matrizes é o cálculo do seu determinante. Veja o que é, e como é feito aqui.
O código abaixo calcula o determinante de uma matriz quadrada 2x2.


#include <stdio.h>
#include <stdlib.h>
 
const int LINHAS = 2;
const int COLUNAS = 2;
 
void preenche_mat_int(int [][2]);
void exibe_mat_int(int [][2]);
int determ_mat_int_2x2(int [][2]);
 
int main(){
 int matriz[2][2], det;
 
 preenche_mat_int(matriz);
 exibe_mat_int(matriz);
 det = determ_mat_int_2x2(matriz);
 printf("O determinante da matriz informada = %d\n", det);
 system("pause");
}
 
int ler_int(){
 int digitado;
 
 printf("Digite um valor inteiro: ");
 scanf("%d",&digitado);
 return digitado;
}
 
void mostra_int(int num){
 printf("%d ",num);
}
 
void preenche_mat_int(int mat[][2]){
 int i, j;
 
 printf("\nPREENCHENDO A MATRIZ:\n");
 for(i = 0; i < LINHAS; i++)
    for(j = 0; j < COLUNAS; j++)
       mat[i][j] = ler_int();
}
 
void exibe_mat_int(int mat[][2]){
 int i, j;
 
 printf("\n");
 for(i = 0; i < LINHAS; i++){
    for(j = 0; j < COLUNAS; j++)
       mostra_int(mat[i][j]);
    printf("\n");
 }
 printf("\n\n");
}
 
int determ_mat_int_2x2(int mat[][2]){
 
 return (mat[0][0] * mat[1][1]) - (mat[0][1] * mat[1][0]);
}


É possível calcular o determinante de uma matriz quadrada de qualquer ordem, mas para isto precisamos ver um conceito que ainda não vimos. Voltarei a este assunto mais a frente.

Até o próximo post.

Um comentário: