1 / 28

Estruturas de Dados Aula 5: Matrizes

Estruturas de Dados Aula 5: Matrizes. 14/04/2014. Matrizes. Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0] linearizado=unidimensional: float mat[3*4]; acesso de elemento: mat[2*3+0] Declaração de um vetor (estática ou dinâmica?) int v[10]

afia
Télécharger la présentation

Estruturas de Dados Aula 5: Matrizes

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Estruturas de DadosAula 5: Matrizes 14/04/2014

  2. Matrizes • Conjuntos bidimensionais declarados estaticamente float mat[4][3]; acesso de elemento: mat[2][0] linearizado=unidimensional: float mat[3*4]; acesso de elemento: mat[2*3+0] • Declaração de um vetor (estática ou dinâmica?) int v[10] int *v; v = (int*) malloc (n*sizeof(int)); v = (int*) realloc (v, m*sizeof(int));

  3. Vetor – declaração estática • int v[10] • Precisamos saber o tamanho do vetor antes da execução do programa • v armazena o endereço de memória ocupado pelo primeiro elemento do vetor *v e v[0] *(v+1) e v[1] • Escopo de declaração local • Se o vetor for declarado dentro da função, não pode ser acessado fora da função

  4. Vetor – declaração dinâmica • int *v; • v = (int*) malloc (n*sizeof(int)); • Tamanho do vetor pode ser definido em tempo de execução do programa • Variável ponteiro aponta para a primeira posição do vetor • Área ocupada pelo vetor permanece fora das funções até que seja liberada explicitamente por free()

  5. Matrizes float mat[4][3] = {{5.0,10.0,15.0}, {20.0,25.0,30.0}, {35.0,40.0,45.0}, {50.0,55.0,60.0}}; Iteracaõ típica sobre todos os elementos: i=0;i<lin;i++ j=0;j<col;j++

  6. Vetores bidimensionais (matrizes) • Elementos acessados pela indexação m[i][j] i acessa linha e j coluna • Elemento inicial m[0][0] • “m” representa um ponteiro para o primeiro “vetor-linha”, composto por 3 elementos. • Pode ser inicializada na declaração: • float mat [4][3] = {1,2,3,4,5,6,7,8,9,10,11,12}; • float mat [][3] = {1,2,3,4,5,6,7,8,9,10,11,12};

  7. Passagem para funções • Tipo passado para função é o “vetor linha” • void f (..., float (*mat)[3], ...); • void f (..., float mat [][3], ...);

  8. Matrizes Dinâmicas • Conjuntos bidimensionais não podem ser alocados dinamicamente no C • Abstrações conceituais com vetores são necessárias para alocarmos matrizes dinamicamente

  9. Matrizes representadas por vetor simples • Matriz é representada por um vetor unidimensional • Primeiras posições do vetor armazenam os elementos da primeira linha • As posições seguintes armazenam da segunda linha, e assim por diante • Conceitualmente, estamos trabalhando com uma matriz • Concretamente, estamos representando um vetor unidimensional • Exige disciplina para acessar os elementos

  10. Matrizes representadas por vetor simples • mat [i][j] V[k], com k = i*n+j, onde n é o número de colunas da matriz

  11. Matriz representada por vetor simples • mat [i][j] mapeado para v[i*n + j] • m e n são as dimensões da matriz (de tamanho m*n elementos) float *mat; ... mat = (float*) malloc (m*n*sizeof(float)); ...

  12. Operações com Matrizes • Exemplo: função transposta • Dada uma matriz, cria dinamicamente a matriz transposta • Matriz de entrada: mat (m x n) • Matriz de saída: trp • Uma matriz Q é a matriz transposta de M, se Qij = Mji float* transposta (int m, int n, float* mat);

  13. Exemplo – matriz com vetor simples float* transposta (int m, int n, float* mat); { int i, j; float* trp; trp = (float*) malloc (n*m*sizeof (float)); for (i=0; i<m; i++) for (j=0; j<n; j++) trp[j*m+i] = mat [i*n+j]; return trp; }

  14. Matriz representada por vetor de ponteiros • Cada linha da matriz é representada por um vetor separado • A matriz é representada por um vetor de vetores • Vetor de ponteiros • Cada elemento do vetor armazena o endereço de memória do primeiro elemento de cada linha

  15. Matriz representada por vetor de ponteiros

  16. Matriz representada por vetor de ponteiros • Precisamos alocar memória para o vetor de ponteiros e atribuir os endereços das linhas da matriz int i; float **mat; /*vetor de ponteiros*/ ... mat = (float**)malloc (m*sizeof(float*)); for (i=0; i<m; i++) mat[i] = (float*) malloc (n*sizeof(float));

  17. Matriz representada por vetor de ponteiros • Para liberar o espaço de memória alocado ... for (i=0; i<m; i++) free (mat[i]); free (mat);

  18. Operações com Matrizes • Exemplo: função transposta • Dada uma matriz, cria dinamicamente a matriz transposta • Matriz de entrada: mat (m x n) • Matriz de saída: trp • Uma matriz Q é a matriz transposta de M, se Qij = Mji float* transposta (int m, int n, float* mat); float** transposta (int m, int n, float** mat);

  19. Exemplo – matriz com vetor simples float* transposta (int m, int n, float* mat); { int i, j; float* trp; trp = (float*) malloc (n*m*sizeof (float)); for (i=0; i<m; i++) for (j=0; j<n; j++) trp[j*m+i] = mat [i*n+j]; return trp; }

  20. Exemplo – matriz com vetor de ponteiros float** transposta (int m, int n, float** mat); { int i, j; float** trp; trp = (float**) malloc (n*sizeof (float*)); for (i=0; i<n; i++) trp[i] = (float*) malloc(m*sizeof(float)); for (i=0; i<m; i++) for (j=0; j<n; j++) trp[j][i] = mat [i][j]; return trp; }

  21. Resumindo • Matriz representada por vetor bidimensional estático: • elementos acessados com indexação dupla m[i][j] • Matriz representada por um vetor simples: • conjunto bidimensional representado em vetor unidimensional • Matriz representada por um vetor de ponteiros: • cada elemento do vetor armazena o endereço do primeiro elemento de cada linha da matriz

  22. Exercício 1 • Implemente a função multiplicação de matriz usando a abordagem de alocação dinâmica de matrizes (vetor de ponteiros) • Multiplicação de matrizes: • entrada: • matriz A de dimensão m x p • matriz B de dimensão p x n • saída: matriz M de dimensão m x n, definida como: para i = 0 até m - 1, de 1 em 1 para j = 0 até n - 1, de 1 em 1 M[ i , j ] = 0 para k = 0 até p - 1, de 1 em 1 M[ i , j ] = M[ i , j ] + A[ i , k ] * B[ k , j ]

  23. Resposta 1) Alocação float **matrix( row, col ) int row, col; { float **a = NULL; int i, j; a = (float**) malloc( row * sizeof(float*) ); if( a == NULL ) { fprintf(stderr,"\nProblema de alocacao !!!\n" ); return NULL; } for( i = 0; i < row; i++ ) { a[i] = (float*) malloc( col * sizeof(float) ); if( a[i] == NULL ) { printf("\nfprintf(stderr,"\nProblema de alocacao !!!\n" ); for( j = 0; j < i; j++ ) FREE( a[j] ); FREE( a ); return NULL; } } return a; }

  24. Resposta 2) Liberação #define FREE(ptr) if(ptr!=NULL){free(ptr);ptr=NULL;} void matrix_free( M, row ) float ***M; int row; { int i; if( (*M) == NULL ) return; if( row == 0 ) EXIT("matrix_free row=0"); for( i = 0; i < row; i++ ) FREE( (*M)[i] ); FREE( (*M) ); } ATENÇÃO: Variável M é modificada dentro da função ==> Passagem por referência. Como M é ponteiro para ponteiro, então passagem de ponteiro para ponteiro para ponteiro.

  25. void matrix_mult( M1, row1, col1, M2, row2, col2, M3, row3, col3 ) float **M1, **M2, ***M3; int row1, col1, row2, col2, *row3, *col3; { int i, j, k; if( col1 != row2 ) { fprintf( stderr, "matrix_mult> Cannot multiply matrices"); fprintf( stderr, " (%d,%d) x (%d,%d). Exit...\n", row1, col1, row2, col2 ); exit(1); } *row3 = row1; *col3 = col2; matrix_free( M3, *row3 ); (*M3) = matrix( *row3, *col3 ); /* Multiply */ for( i = 0; i < *row3; i++ ) { for( j = 0; j < *col3; j++) { (*M3)[i][j] = 0.0; for( k = 0; k < col1; k++ ) (*M3)[i][j] += M1[i][k] * M2[k][j]; } } } Resposta 3) Multiplicação

  26. Resposta 4) Uso extern float **matrix(); // pode ser incluído em arq. de cabeçalho (.h) ... int linA, colA, linB, colB, linM, colM; float **A = NULL, **B=NULL, **M=NULL; ... A = matrix(linA,colA); B = matrix(linb,colB); … matrix_mult( A, linA, colA, B, linB, colB, &M, &linM, &colM ); ... matrix_free( &A, linA ); matrix_free( &B, linB ); matrix_free( &M, linM ); // Pós-condição: A==NULL, B==NULL, M==NULL, e memória liberada

  27. Resposta

  28. Exercício 2 • Implemente a função multiplicação usando a abordagem de alocação dinâmica de matrizes (representada por vetor simples) → veja 'matrix.c'

More Related