Estudos de Caso com Matrizes
INF01202
Prof. Lucas Mello Schnorr
Sumário
Revisão
Estudos de caso
I #1 (turma, nome de alunos, suas notas, média e conceito) I #2 (matriz esparsa para condensada)
I #3 (permutação de palavra) I #4 (percorrimentos em matrizes)
I #4.1 (diagonal) Exercícios
I #4 (percorrimentos em matrizes) I #4.2 (diferentes formas geométricas) I #5 (multiplicação de matrizes)
Desao
I Campo minado
2 / 21
(Revisão) Arranjos multidimensionais
Slide 2 Prof. EDison
Arranjos de mais de uma dimensão Matrizes
Arranjos de n>2 dimensões
Cortesia: Prof. Edison Pignaton de Freitas
(Revisão) Ainda sobre strings
Slide 3 Prof. EDison
Strings são cadeias ou sequências de caracteres.
Em C, as strings são vetores de caracteres que têm como característica apresentar o caractere delimitador de fim ‘\0’
(caractere da posição 0 da tabela ASCII – não é o dígito 0).
Importante: toda string é um vetor de caracteres, mas nem todo vetor de caracteres é uma string (pois pode não apresentar o delimitador ‘\0’)
Exemplo: vetor de caracteres vet de 9 posições, apenas com as posições de 0 a 6 ocupadas (outras posições com “lixo”):
N caracteres = string
b r a s i l \0 ? ?
0 1 2 3 4 5 6 7
vet
8
Cortesia: Prof. Edison Pignaton de Freitas 4 / 21
#1 (nome de alunos, 3Ö notas, média)
Para uma turma de NALUNOS alunos, para cada aluno: ler o nome do aluno (até 12 caracteres); ler as 3 notas obtidas por este aluno; calcular a média obtida.
Vamos simplicar
I Ler apenas os nomes dos NALUNOS (até 12 caracteres)
I Vamos usar uma string auxiliar de validação e controle
#1 (nome de alunos, 3Ö notas, média)
Para uma turma de NALUNOS alunos, para cada aluno: ler o nome do aluno (até 12 caracteres); ler as 3 notas obtidas por este aluno; calcular a média obtida.
Vamos simplicar
I Ler apenas os nomes dos NALUNOS (até 12 caracteres) I Vamos usar uma string auxiliar de validação e controle
5 / 21
(#1) Code a17-nomes.c
#include <stdio.h>
#include <string.h>
#define NALUNOS 2
#define NOME_MAX 12 //maior qtadade de caracteres
#define AUXILIAR_MAX 200 intmain() {
//nome com tamanho máximo de 12 caracteres charnome[NALUNOS][NOME_MAX+1];
//variável auxiliar na leitura da cada nome charaux[AUXILIAR_MAX];
//índice para os nomes inta;
// leitura dos dados for(a= 0; a<NALUNOS; a++){
printf("Dados do aluno %d:\n", a+ 1);
printf("\tNome: ");
//Vamos ler o nome na variável auxiliar fgets(aux, AUXILIAR_MAX, stdin);
aux[strlen(aux)-1]='\0';//remove o \n while(strlen(aux)>NOME_MAX){
printf("Nome muito longo (%d bytes), "
"deve ser %d bytes no máximo.\n", strlen(aux), NOME_MAX);
printf("\tNome: ");
fgets(aux, AUXILIAR_MAX, stdin);
aux[strlen(aux)-1]='\0';//remove o \n }
//Vamos copiar para destino final strncpy (nome[a], aux, NOME_MAX);
}
//imprimir todos os nomes lidos for(a= 0; a<NALUNOS; a++){
printf("Aluno %d:\"%s\"\n", a+1, nome[a]);
}return0;
}
#1 (nome de alunos, 3Ö notas, média)
Para uma turma de NALUNOS alunos, para cada aluno: ler o nome do aluno (até 12 caracteres); ler as 3 notas obtidas por este aluno; calcular a média obtida.
7 / 21
(#1) Code a17-turma.c
#include <stdio.h>
#include <string.h>
#define NALUNOS 2
#define NNOTAS 3 //quantidade de notas
#define NOME_MAX 12 //maior qtadade de caracteres
#define AUXILIAR_MAX 200 intmain() {
//com a média calculada na última coluna floatnota[NALUNOS][NNOTAS+1];
//nome com tamanho máximo de 12 caracteres charnome[NALUNOS][NOME_MAX+1];
//variável para auxilair na leitura da cada nome charaux[AUXILIAR_MAX];
//índice para os nomes e notas inta, n;
//acumulador das notas para média floatsoma;
// leitura de dados
for(a= 0; a<NALUNOS; a++){
printf("Dados do aluno %d:\n", a+ 1);
printf("\tNome: ");
//Vamos ler o nome na variável auxiliar fgets(aux, AUXILIAR_MAX, stdin);
aux[strlen(aux)-1]='\0';//remove o \n while(strlen(aux)>NOME_MAX){
printf("Nome muito longo (%d bytes), "
"deve ser %d bytes no máximo.\n", strlen(aux), NOME_MAX);
printf("\tNome: ");
fgets(aux, AUXILIAR_MAX, stdin);
aux[strlen(aux)-1]='\0';//remove o \n }
//Vamos copiar para destino final strncpy (nome[a], aux, NOME_MAX);
//Vamos ler as três notas soma= 0;
for(n= 0; n<NNOTAS; n++){
printf("\tNota %d: ", n+ 1);
scanf("%f",¬a[a][n]);
soma+=nota[a][n];
//limpa o buffer de entrada charc;
while((c=getchar())!='\n'&&c!=EOF);
}nota[a][n]=soma/NNOTAS;
}
//imprimir todos os nomes lidos for(a= 0; a<NALUNOS; a++){
printf("Aluno %d:\"%s\", com notas: ", a+1, nome[a]);
for(n= 0; n<NNOTAS; n++){
printf("%.2f ", nota[a][n]);
}printf("e média %.2f.\n", nota[a][n]);
}return0;
}
(#1++) Code a17-conceito.c (com conceito)
#include <stdio.h>
#include <string.h>
#define NALUNOS 2
#define NNOTAS 3 //quantidade de notas
#define NOME_MAX 12 //maior qtadade de caracteres
#define AUXILIAR_MAX 200 intmain() {
//vetor com os conceitos de cada aluno charconceito[NALUNOS];
//com a média calculada na última coluna floatnota[NALUNOS][NNOTAS+1];
//nome com tamanho máximo de 12 caracteres charnome[NALUNOS][NOME_MAX+1];
//variável para auxilair na leitura da cada nome charaux[AUXILIAR_MAX];
//índice para os nomes e notas inta, n;
//acumulador das notas para média floatsoma;
// leitura de dados
for(a= 0; a<NALUNOS; a++){
printf("Dados do aluno %d:\n", a+ 1);
printf("\tNome: ");
//Vamos ler o nome na variável auxiliar fgets(aux, AUXILIAR_MAX, stdin);
aux[strlen(aux)-1]='\0';//remove o \n while(strlen(aux)>NOME_MAX){
printf("Nome muito longo (%d bytes), "
"deve ser %d bytes no máximo.\n", strlen(aux), NOME_MAX);
printf("\tNome: ");
fgets(aux, AUXILIAR_MAX, stdin);
aux[strlen(aux)-1]='\0';//remove o \n }//Vamos copiar para destino final strncpy (nome[a], aux, NOME_MAX);
//Vamos ler as três notas soma= 0;
for(n= 0; n<NNOTAS; n++){
printf("\tNota %d: ", n+ 1);
scanf("%f",¬a[a][n]);
soma+=nota[a][n];
//limpa o buffer de entrada charc;
while((c=getchar())!='\n'&&c!=EOF);
}nota[a][n]=soma/NNOTAS;
//Define conceito
if(nota[a][n]> 8.5) conceito[a]='A';
else if(nota[a][n]> 7.5) conceito[a]='B';
else if(nota[a][n]> 6.0) conceito[a]='C';
elseconceito[a] ='D';
}//imprimir
for(a= 0; a<NALUNOS; a++){
printf("Aluno %d:\"%s\", com notas: ", a+1, nome[a]);
for(n= 0; n<NNOTAS; n++){
printf("%.2f ", nota[a][n]);
}printf("média %f, conceito %c\n", nota[a][n], conceito[a]);
}return0;
}
9 / 21
#2 (matriz esparsa para condensada)
Slide 12 Prof. EDison
Exercício
1. Uma matriz esparsa é uma matriz que tem aproximadamente 2/3 de seus elementos iguais a zero. Fazer um programa que lê (linha à linha) uma matriz esparsa me(MAXL,MAXC) contendo valores inteiros e forma uma matriz condensada mc, de apenas três colunas, contendo os elementos não nulos de M, de forma que:
• a primeira coluna contém os valores não nulo de me;
• a segunda coluna contém a linha de me onde foi encontrado o valor armazenado na coluna 1;
• a terceira coluna contém a coluna de me onde foi encontrado o valor armazenado na coluna 1.
Imprimir as duas matrizes, APÓS o preenchimento da matriz condensada!
- Determinar o número de linhas de mc faz parte do problema.
- Testar o programa com os seguintes dados de entrada:
0 0 -1 0 2 -3 0 0 4 0 0 -5 0 0 0 0 0 0 6 0 0 -7 0 0 8 (linha 1) (linha 2) (linha 3) (linha 4) (linha 5)
Cortesia: Prof. Edison Pignaton de Freitas
(#2) Exemplo
0 0 − 1 0 2
− 3 0 0 4 0
0 − 5 0 0 0
0 0 0 6 0
0 − 7 0 6 8
→
− 1 0 2
2 0 4
− 3 1 0
4 1 3
− 5 2 2
6 3 3
− 7 4 1
6 4 3
8 4 4
11 / 21
(#2) Code
#include <stdio.h>
#define MAXL 5 // número de linhas
#define MAXC 5 // número de colunas intmain() {
//a matriz esparsa
intesparsa[MAXL][MAXC]={0};
//a matriz condensada com mais ou menos 1/3 dados intcondensada[(MAXL*MAXC)/3+1][3]={0};
//índices da esparsa intl, c;
//índice linha da condensada intlc;
//leitura dos dados for(l= 0; l<MAXL; l++) {
for(c= 0; c<MAXC; c++) { printf("Elemento [%d][%d]: ", l, c);
scanf("%d",&esparsa[l][c]);
}}
//percorre esparsa
lc= 0;//zero o índice da condensada for(l= 0; l<MAXL; l++) {
for(c= 0; c<MAXC; c++) { if(esparsa[l][c]){
condensada[lc][0]=esparsa[l][c];
condensada[lc][1]=l;
condensada[lc][2]=c;
lc++;
}} } //imprime printf("\n");
printf("Esparsa\n");
for(l= 0; l<MAXL; l++) { for(c= 0; c<MAXC; c++) {
printf("%2d ", esparsa[l][c]);
}printf("\n");
} //imprime
printf("Condensada\n");
for(l= 0; l<(MAXL*MAXC)/3+1; l++) { for(c= 0; c< 3; c++) {
printf("%2d ", condensada[l][c]);
}printf("\n");
}return0;
}
(#2) Teste
0 0 −1 0 2
−3 0 0 4 0
0 −5 0 0 0
0 0 0 6 0
0 −7 0 6 8
→
−1 0 2
2 0 4
−3 1 0
4 1 3
−5 2 2
6 3 3
−7 4 1
6 4 3
8 4 4
Vejamos
gcc a17-esparsa.c
echo"0 0 -1 0 2 -3 0 0 4 0 0 -5 0 0 0 0 0 0 6 0 0 -7 0 6 8"| ./a.out
Elemento [0][0]: Elemento [0][1]: Elemento [0][2]: Elemento [0][3]: Elemento [0][4]: Elemento [1][0]: Elemento [1][1]: Elemento [1][2]: Elemento [1][3]: Elemento [1][4]: Elemento [2][0]: Elemento [2][1]: Elemento [2][2]: Elemento [2][3]: Elemento [2][4]: Elemento [3][0]: Elemento [3][1]: Elemento [3][2]: Elemento [3][3]: Elemento [3][4]: Elemento [4][0]: Elemento [4][1]: Elemento [4][2]: Elemento [4][3]: Elemento [4][4]:
Esparsa 0 0 -1 0 2 -3 0 0 4 0 0 -5 0 0 0 0 0 0 6 0 0 -7 0 6 8 Condensada -1 0 2
2 0 4 -3 1 0 4 1 3 -5 2 1 6 3 3 -7 4 1 6 4 3 8 4 4
13 / 21
#3 (permutação de palavra)
Slide 16 Prof. EDison
Exercício
2. Uma palavra é a permutação circular de outra se for obtida com a transferência do caractere do início para o fim da mesma. Ex : AROMA → ROMAA
Faça um programa que leia uma string de até 16 caracteres e informe a permutação circular da palavra lida.
Algoritmo permutação (não refinado) 1. inicio
2. ler palavra
3. permuta recebe permutação de palavra // preserva entrada 3. escreve permuta
4. fim.
A R R O
O M
M A
A A
[0]
[1]
[2]
[3]
[4]
[0]
[1]
[2]
[3]
[4]
Cortesia: Prof. Edison Pignaton de Freitas
(#3) Code
// Gera permutação circular
#include <stdio.h>
#include <string.h>
#define SIZEPAL 16 int main() {
//a palavra lida
char palavra[SIZEPAL+1];
//a palavra permutada char permuta[SIZEPAL+1];
//para salvar tamanho int tamanho;
//índice de percorrimento na string int i;
//Vamos ler a palavra printf("Palavra: ");
fgets(palavra, SIZEPAL, stdin);
tamanho = strlen(palavra);
//remove o \n
palavra[tamanho-1] = '\0';
//atualiza tamanho
tamanho = strlen(palavra);
printf("\n\nPalavra: [%s]\n",palavra);
// do 1 até penúltimo caractere // recebem o da posição posterior for (i = 0; i < (tamanho-1); i++){
permuta[i] = palavra[i+1];
} // último caractere da permuta // recebe primeiro da palavra permuta[i] = palavra[0];
// inserir terminador permuta[i+1] = '\0';
printf("Permuta: [%s]\n",permuta);
return 0;
}
O que acontece se #define SIZEPAL 3?
15 / 21
(#3) Code
// Gera permutação circular
#include <stdio.h>
#include <string.h>
#define SIZEPAL 16 int main() {
//a palavra lida
char palavra[SIZEPAL+1];
//a palavra permutada char permuta[SIZEPAL+1];
//para salvar tamanho int tamanho;
//índice de percorrimento na string int i;
//Vamos ler a palavra printf("Palavra: ");
fgets(palavra, SIZEPAL, stdin);
tamanho = strlen(palavra);
//remove o \n
palavra[tamanho-1] = '\0';
//atualiza tamanho
tamanho = strlen(palavra);
printf("\n\nPalavra: [%s]\n",palavra);
// do 1 até penúltimo caractere // recebem o da posição posterior for (i = 0; i < (tamanho-1); i++){
permuta[i] = palavra[i+1];
} // último caractere da permuta // recebe primeiro da palavra permuta[i] = palavra[0];
// inserir terminador permuta[i+1] = '\0';
printf("Permuta: [%s]\n",permuta);
return 0;
}
O que acontece se #define SIZEPAL 3?
#4.1 (diagonal)
Slide 19 Prof. EDison
Preencher por leitura uma matriz M (5,5).
Em seguida, calcular e imprimir a média dos elementos da diagonal principal:
Exercícios
m[0,0]
m[1,1]
m[2,2]
m[3,3]
m[4,4]
linha: 0 a 4 coluna: 0 a 4 linha == coluna!!!
Cortesia: Prof. Edison Pignaton de Freitas 16 / 21
(#4.1) Code
#include <stdio.h>
#include <stdlib.h>
//Limites da nossa matriz
#define ORDEM 15
//Limites de valores aleatórios
#define MIN 1
#define MAX 99 int main(){
//A matriz m e seus índices int m[ORDEM][ORDEM] = {0};
int l, c;
//acumulador da soma int soma;
// Define a semente para aleatórios srand(0);
// inicializar a matriz // com valores aleatórios for (l = 0; l < ORDEM; l++)
for (c = 0; c < ORDEM; c++)
m[l][c] = MIN+(rand()%(MAX-MIN+1));
// somatório da diagonal principal soma = 0;
for (l = 0; l < ORDEM; l++){
soma += m[l][l];
}
// imprimir a matriz printf("Matriz\n");
for (l = 0; l < ORDEM; l++){
for (c = 0; c < ORDEM; c++) printf("%2d ", m[l][c]);
printf("\n");
} printf("Média da diagonal: %.2f\n", (float)soma/ORDEM);
return 0;
}
Exercício #1 (diferentes formas geométricas)
Slide 22 Prof. EDison
Preencher por leitura uma matriz M (5,5).
Em seguida, calcular e imprimir a média dos elementos das áreas assinaladas:
Exercícios
Cortesia: Prof. Edison Pignaton de Freitas 18 / 21
Exercício #2 (multiplicação de matrizes)
Seja
I A uma matriz de dimensão r x s I B uma matriz de dimensão s x t.
Faça um programa que calcula o produto de A x B, resultando em uma matriz C de dimensão r x t.
Exemplo
1 2 3 4 5 6 7 8
×
1 2 3 4 5 6 7 8
=
1 ∗ 1 + 2 ∗ 3 + 3 ∗ 5 + 4 ∗ 7 1 ∗ 2 + 2 ∗ 4 + 3 ∗ 6 + 4 ∗ 8
5 ∗ 1 + 6 ∗ 3 + 7 ∗ 5 + 8 ∗ 7 5 ∗ 2 + 6 ∗ 4 + 7 ∗ 6 + 8 ∗ 8
Estudo de caso para multiplicação de matrizes
Uma pessoa preparou três receitas usando quatro ingredientes em proporções variadas, conforme a tabela 1. Os preços unitários dos ingredientes constam da tabela 2. Determine a matriz (tabela 3) que registra o preço total de cada Receita.
Tabela #1
Receita A B C D
1 3 6 1 3
2 4 4 2 2
3 0 1 1 6
Tabela #2
Ingrediente Valor
A 0.2
B 0.8
C 1.2
D 2.8
20 / 21