Buscar

Prog I - Aula 12: matrizes

Prévia do material em texto

Matrizes
INF1005 – Programação I – 33B
Prof. Gustavo Moreira
gmoreira@inf.puc-rio.br 
1
matrizes
tópicos
declaração (alocação estática)
operações com matrizes
referênciareferência
Capítulo 8 da apostila
Capítulo 6 do livro
2
vetores bidimensionais: matrizes
declarando com [linhas] e [colunas]:
float m[4][3];
já inicializando:
float m[4][3] = {
{5.0, 10.0, 9.0}, 
{2.0, 2.0, 3.0}, 
152
6.0
5.0
5.0
5.0
4.0linha 3
linha 4
m[3] [0]
{2.0, 2.0, 3.0}, 
{3.0, 4.0, 5.0}, 
{5.0, 5.0, 6.0}
};
3
5.0 10.0 9.0
2.0 2.0 3.0
3.0 4.0 5.0
5.0 5.0 6.0
coluna j
linha i
4.0
3.0
3.0
2.0
2.0
9.0
10.0
5.0
104
linha 1
linha 2
linha 3
m[0][0]
m[1] [0]
m[2] [0]
m[2][1]
vetores bidimensionais: matrizes
outras formas de inicializar a mesma matriz:
float m[4][3] = 
{5.0, 10.0, 9.0, 2.0, 2.0, 3.0, 3.0, 4.0, 5.0, 5.0, 5.0, 6.0};
float m[ ][3] = 
{5.0, 10.0, 9.0, 2.0, 2.0, 3.0, 3.0, 4.0, 5.0, 5.0, 5.0, 6.0};{5.0, 10.0, 9.0, 2.0, 2.0, 3.0, 3.0, 4.0, 5.0, 5.0, 5.0, 6.0};
4
5.0 10.0 9.0
2.0 2.0 3.0
3.0 4.0 5.0
5.0 5.0 6.0
passando matriz alocada estaticamente 
para funções
protótipos de funções que recebem matrizes:
void imprime_matriz (int linhas, int cols, float (*mat)[3]);
ou
void imprime_matriz (int linhas, int cols, float mat[ ][3]);
5
void imprime_matriz (int linhas, int colunas, float mat[ ][3])
{
int i, j;
for (i=0; i < linhas; i++)
for (j=0; j < colunas; j++)
printf("linha %d, coluna %d: elemento %f\n", i, j, mat[i][j]);
}
exercícios
1. Considerando que a matriz abaixo representa um conjunto de 
3 notas de 4 alunos, escreva um programa que calcule e 
imprima a média de cada aluno e a média da turma.
float m[4][3] = 
{5.0, 10.0, 9.0, 2.0, 2.0, 3.0, 3.0, 4.0, 5.0, 5.0, 5.0, 6.0};
EX. 01
2. Modifique o programa para ler do teclado a “posição" de um 
aluno (de 1 a 4) e imprimir a sua média. O programa deve
continuar lendo números de aluno até que um número inválido
seja fornecido pelo usuário.
3. Modifique o programa anterior para ler as notas dos alunos de 
um arquivo notas.txt.
6
exercício
Escreva uma função que receba uma matriz quadrada NxN e 
verifique se ela é simétrica. A função deve retornar 1 caso a matriz
seja simétrica; ou 0, caso contrário. Considere que N foi definido
da seguinte maneira:
#define N 4
EX. 02
________________________________________________________________________
________________________________________________________________________
7
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
exercício
Escreva uma função que receba uma matriz quadrada NxN e 
verifique se ela é simétrica. A função deve retornar 1 caso a matriz
seja simétrica; ou 0, caso contrário. Considere que N foi definido
da seguinte maneira:
#define N 4
EX. 02
int simetrica (double mat[ ][N])
{
8
{
int i, j;
for (i=0; i < N; i++) {
for (j=0; j < i; j++) {
if (mat[i][j] != mat[j][i]) {
return 0;
}
}
}
return 1;
}
exercício
Escreva uma função que calcule a transposta de uma matriz
quadrada NxN. Considere que N foi definido da seguinte maneira:
#define N 4
EX. 03
void cria_transposta(double orig[][N], double transp[][N])
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
9
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
exercício
Escreva uma função que calcule a transposta de uma matriz
quadrada NxN. Considere que N foi definido da seguinte maneira:
#define N 4
EX. 03
void cria_transposta(double orig[][N], double transp[][N])
{
int i, j;
for (i=0; i < N; i++) {
10
for (i=0; i < N; i++) {
for (j=0; j < N; j++) {
transp[j][i] = orig[i][j];
}
}
}
exercício
Assumindo que não haja espaço alocado para uma segunda
matriz, escreva uma função que transponha uma matriz quadrada
NxN, sobrescrevendo a matriz original. Considere que N foi
definido da seguinte maneira:
#define N 4
EX. 04
void transpoe(double mat[][N])
________________________________________________________________________
11
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
exercício
Assumindo que não haja espaço alocado para uma segunda
matriz, escreva uma função que transponha uma matriz quadrada
NxN, sobrescrevendo a matriz original. Considere que N foi
definido da seguinte maneira:
#define N 4
EX. 04
void transpoe(double mat[][N])
{
12
{
int i, j;
for (i=0; i < N; i++) {
for (j=0; j < i; j++) {
double t = mat[i][j];
mat[i][j] = mat[j][i];
mat[j][i] = t;
}
}
}
exercício
Escreva uma função que multiplique uma matriz quadrada NxN por
um escalar. Considere que N foi definido da seguinte maneira:
#define N 4
EX. 05
void mat_mult_escalar (double orig[][N], double mult[][N], double valor)
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________13
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
exercício
Escreva uma função que multiplique uma matriz quadrada NxN por
um escalar. Considere que N foi definido da seguinte maneira:
#define N 4
EX. 05
void mat_mult_escalar (double orig[][N], double mult[][N], double valor)
{
int i, j;
for (i=0; i < N; i++) {
14
for (i=0; i < N; i++) {
for (j=0; j < N; j++) {
mult[i][j] = valor * orig[i][j];
}
}
}
exercício
Escreva uma função que multiplique uma matriz NxN por um vetor
de tamanho N. Considere que N foi definido da seguinte maneira:
#define N 4
EX. 06
void mat_mult_vetor (double mat[][N], double orig[], double mult[])
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
15
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
exercício
Escreva uma função que multiplique uma matriz NxN por um vetor
de tamanho N. Considere que N foi definido da seguinte maneira:
#define N 4
EX. 06
void mat_mult_vetor (double mat[][N], double orig[], double mult[])
{
int i, j;
for (i=0; i < N; i++) {
16
for (i=0; i < N; i++) {
mult[i] = 0.0;
for (j=0; j < N; j++) {
mult[i] = mult[i] + mat[i][j] * orig[j];
}
}
}
exercício
Escreva uma função que multiplique duas matrizes NxN. Considere
que N foi definido da seguinte maneira:
#define N 4
EX. 07
void mat_mult_matriz (double a[][N], double b[][N], double c[][N])
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
17
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
exercício
Escreva uma função que multiplique duas matrizes NxN. Considere
que N foi definido da seguinte maneira:
#define N 4
EX. 07
void mat_mult_matriz (double a[][N], double b[][N], double c[][N])
{
int i, j, k;
for (i=0; i < N; i++) {
18
for (i=0; i < N; i++) {
for (j=0; j < N; j++) {
c[i][j] = 0.0;
for (k=0; k < N; k++) {
c[i][j] = c[i][j] + a[i][k] * b[k][j];
}
}
}
}
matrizes dinâmicas
C só permite alocação dinâmica de conjuntos unidimensionais
cria-se uma abstração conceitual de matriz
para uma matriz mat de dimensões m x n, cria-se um 
vetor vmat
dimensão do vetor vmat: m * n
float *vmat;
vmat = (float *) malloc (m * n * sizeof(float));
elemento mat[i][j] passa a ser o elemento vmat [ i * n + j]
19
matriz como vetor de ponteiros
cada elemento armazena o endereço do primeiro 
elemento de cada linha
20
int i;
float **mat; /* vetor de ponteiros */
/* aloca vetor de m ponteiros */
mat = (float**) malloc (m*sizeof(float*));
/* aloca vetor de n elementos (colunas) em cada 
linha */
for (i=0; i < m; i++)
mat[i] = (float*) malloc(n*sizeof(float));
operações com matrizes
transposta de matriz representada como vetor simples
/* Solução 1: matriz m x n alocada como vetor simples */
float* transposta (int m, int n, float* mat)
{
int i, j;
float* trp;
21
/* aloca matriz transposta com n linhas e m colunas */
trp = (float*) malloc (n * m * sizeof(float));
/* preenche matriz */
for (i=0; i < m; i++)
for (j=0; j < n; j++)
trp[ j * m + i ] = mat[ i * n + j ];
return trp;
}
operações com matrizes
transposta de matriz representada como vetor de 
ponteiros
/* Solução 2: matriz alocada como vetor de ponteiros */
float** transposta (int m, int n, float** mat)
{
int i, j;
float** trp;
22
/* aloca matriz transposta com n linhas e m colunas */
trp = (float**) malloc (n * sizeof(float*));
for (i=0; i<n; i++)
trp[i] = (float*) malloc(m * sizeof(float));
/* preenche matriz */
for (i=0; i<m; i++)
for (j=0; j<n; j++)
trp[ j ] [ i ] = mat[ i ][ j ];
return trp;
}
operação com matrizes – transposta
/* Solução 1: matriz m x n alocada como 
vetor simples */
float* transposta (int m, int n, float* mat)
{
int i, j;
float* trp;
/* aloca matriz transposta com
n linhas e m colunas */
trp = (float*) malloc (n * m * 
/* Solução 2: matriz m x n alocada como 
vetor de ponteiros */
float** transposta (int m, int n, float** mat)
{
int i, j;
float** trp;
/* aloca matriz transposta com 
n linhas e m colunas */
trp = (float**) malloc (n * sizeof(float*));
23
trp = (float*) malloc (n * m * 
sizeof(float));
/* preenche matriz */
for (i=0; i < m; i++)
for (j=0; j < n; j++)
trp[ j * m + i ] = mat[ i * n + j ];
return trp;
}
trp = (float**) malloc (n * sizeof(float*));
for (i=0; i<n; i++)
trp[i] = (float*) malloc(m * 
sizeof(float));
/* preenche matriz */
for (i=0; i<m; i++)
for (j=0; j<n; j++)
trp[ j ] [ i ] = mat[ i ][ j ];
return trp;
}
matrizes simétricas
matriz n x n, onde mat[i][j] = mat [j][i]
em vez de armazenar n2 valores, pode-se 
armazenar apenas os valores da diagonal e 
abaixo dela 1 2 3abaixo dela
24
2
1) (n n 
 n ... 3 2 1 s +=++++=
1 2 3
2 4 5
3 5 6
12 4 3 5 6
matrizes simétricas
para acessar o elemento mat[i][j], precisamos 
pular 1+2+...+i elementos para acessar a linha 
i e mais j para acessar a coluna
1 2 3
25
2
1) (n n 
 n ... 3 2 1 s +=++++=
1 2 3
2 4 5
3 5 6
1 2 4 3 5 6
25
i = 2, j = 1
k = i*(i+1)/2 + j
k = 4
mat[i][j]
mat[2][1]
v[i*(i+1)/2+j]
v[4]
matrizes simétricas
/* Solução 1: matriz alocada como vetor simples 
*/
float* cria (int n)
{
int s = n*(n+1)/2;
float* mat = (float*) 
malloc(s*sizeof(float));
return mat;
}
float acessa (int n, float* mat, int i, int j)
/* Solução 2: matriz alocada como vetor de 
ponteiros */
float** cria (int n)
{
int i;
float** mat = (float**) 
malloc(n*sizeof(float*));
for (i=0; i<n; i++)
mat[i] = (float*) 
malloc((i+1)*sizeof(float));
return mat;
}
26
float acessa (int n, float* mat, int i, int j)
{
int k; /* índice do elemento no vetor */
if (i<0 || i>=n || j<0 || j>=n) {
printf("Acesso inválido!\n”);
exit(1);
}
if (i >= j) /* se estiver na diagonal ou
abaixo */
/* acessa elemento representado */
k = i*(i+1)/2 + j; 
else
/* acessa elemento simétrico */
k = j*(j+1)/2 + i; 
return mat[k];
}
float acessa (int n, float** mat, int i, int j)
{
if (i<0 || i>=n || j<0 || j>=n) {
printf("Acesso inválido!\n”);
exit(1);
}
if (i >= j) /* se estiver na diagonal ou
abaixo */
/* acessa elemento representado */
return mat[ i ] [ j ]; 
else
/* acessa elemento simétrico */
return mat[ j ][ i ]; 
}
dúvidas?dúvidas?
27
Prof. Gustavo Moreira
gmoreira@inf.puc-rio.br

Continue navegando