A maior rede de estudos do Brasil

Grátis
2 pág.
AtividadeDidatica_05b

Pré-visualização | Página 1 de 1

Universidade Federal do Ceará – Departamento de Engenharia de Teleinformática
Atividade Didática Remota – 2021.1
Introdução à Programação
Prof. Tarcisio Ferreira Maciel, Dr.-Ing.
Objetivos:
• Explorar programas que utilizemmatrizes.
Critérios de avaliação:
i. Correção: o programa deve fornecer respostas corretas. Redução em até 100% da nota.
ii. Cobertura: o programa deve utilizar tipos de dados e comandos corretos para processar adequadamente
diferentes entradas. Redução em até 50% da nota cumulativa com outros critérios.
iii. Organização: o programa deve estar devidamente organizado (indentação, nomes de identificadores claros,
comentários, etc.). Redução em até 10% na nota cumulativa com outros critérios.
iv. Originalidade: o programa não deve ser cópia literal ou cópia semântica (p. ex., cópia literal com termos
renomeados) da solução de outro discente. Redução em até 50% da nota cumulativa com outros critérios.
Para cada questão de programação da atividade, comece criando uma aplicação do tipo “Console application”
seguindoopasso-a-passoapresentadoemvídeo. Emseguida,modifiqueoprograma“HelloWorld!” para resolver
uma questão. Cada projeto deverá ser chamado QuestaoXX, em que XX é o número da questão. Por exemplo,
para a Questão 1, o projeto deverá se chamar Questao01. Em todas as questões é mandatório que os dados de
entrada fornecidos pelo usuário sejamvalidados. Para questões que exigema criaçãodeumaoumais funções,
as mesmas devem ser fazer parte de uma biblioteca própria de funções composta por dois arquivos: i) o arquivo
de declarações que deverá se chamar funcoes.hpp e; ii) pelo arquivo de implementação funcoes.cpp.
O exemplo abaixo mostra uma técnica avançada para passar uma matriz por referência para uma função em
C++. O exemplo utiliza um template com parâmetros e explora a habilidade do compilador de inferir o tipo e
as dimensões da matriz passada para construir uma função genérica que imprime matrizes de qualquer tipo e
tamanho.
#include <iostream>
using namespace std;
template <short nRows, short nCols, typename T> void printMatrix(T (&A)[nRows][nCols]) {
for(short i = 0; i < nRows; ++i) {
for(short j = 0; j < nCols; ++j) {
cout << A[i][j] << ' ';
}
cout << '\n';
}
}
int main() {
short A[3][2] = {1, 2, 3, 4, 5, 6};
float B[2][3] = {0.5, 1.1, 1.5, 2.1, 2.5, 3.1};
cout << "A" << endl;
printMatrix(A); // Note que nRows, nCols e T não foram citados
cout << "B" << endl;
printMatrix(B); // Note que além disso, agora o tipo é float e não mais short
}
Como se vê, esta técnica permite passar não só matrizes de diferentes tamanhos, mas também de diferentes
tipos para umamesma função e, seguindoomodelo de seu cabeçalho, outras funções comcapacidades similares
podem ser implementadas. Esta porém não é a forma tradicional de se passar umamatriz para uma função. Nas
questões abaixo, a forma tradicional é considerada, a qual passa amatriz para uma função comoa referência para
um array unidimensional que deve ser adequadamente indexado dentro da função. Lembre-se que, namemória,
uma matriz de dimensões # × " assemelha-se a um vetor de tamanho # · " . A primeira questão abaixo dá
maiores detalhes sobre esse processo de endereçamento dos elementos damatriz.
Questão 1. Um vetor v ∈ R#×1 é normalmente passado para uma função na forma de um ponteiro *v (que
é equivalente a escrever v[]) acompanhado de seu tamanho N. Dentro da função, os elementos E8 do vetor v
são acessados da forma convencional usando v[i]. Uma matriz G ∈ R#×" também é normalmente passada
para uma função na forma de um ponteiro *A passado como &A[0][0] acompanhado das dimensões de N linhas
e M colunas. Porém, para acessar o elemento �8 9 da matriz (ou seja, o elemento A[i][j]) dentro da função, é
necessário escrever A[i*M + j] que endereça o elemento desejado na memória associada à matriz. Com base
nessas informações, escreva uma função void sum(float *A, float *v, const short N, const short M)
que recebapor referênciaumamatrizAdedimensãoN linhasporM colunasepor referênciaumvetorvde tamanho
N. A função sum deve somar os elementos de 8-ésima linha de G e armazenr o resultado no 8-ésimo elemento de v.
Logo, o vetor v deverá conter as somas dos elementos de G linha-a-linha. Na função main crie umamatriz A com
N = 3 linhas e M = 4 colunas e um vetor v de tamanho adequado. Ainda na main, leia os elementos damatriz via
teclado e utilize a função sum para calcular a soma de cada linha de A em v. Em seguida, imprima os elementos
de v na função main.
Questão 2. Umamatriz de Vandermonde é umamatriz # × # da forma
G =

_00 _
1
0 _
2
0 . . . _
#−1
0
_01 _
1
1 _
2
1 . . . _
#−1
1
_02 _
1
2 _
2
2 . . . _
#−1
2
...
...
...
. . .
...
_0
#−1 _
1
#−1 _
2
#−1 . . . _
#−1
#−1

definida em função de um vetor , =
[
_0 _1 _2 . . . _#−1
]T. Escreva uma função
void vandermonde(float *lambda, short N, float *A) que recebe como parâmetro o vetor lambda de
tamanho N contendo os valores de _0, · · · , _#−1 e que retorne, através do parâmetro A (passado por referência
usando ponteiro) a matriz G preenchida conforme a fórmula acima. Na função main, crie e leia um vetor lambda
de tamanho 3, o qual deve ser definido usando const. Crie também uma matriz A de dimensões adequadas.
Ainda na main, chame a função vandermonde para preencher A a partir de lambda conforme a definição acima.
Em seguida, imprima na função main a matriz resultante.
Questão 3. Considere uma matriz contendo as notas de três avaliações de uma turma com # = 10 alunos.
Escreva um programa que leia essa matriz de notas e que calcule a média das avaliações de cada aluno
guardando-as em um vetor de médias. Após a determinação das médias, o seu programa deve determinar
também quais os percentuais de alunos com média < nos intervalos 0 ≤ < ≤ 1, 1 < < ≤ 2, 2 < < ≤ 3,
. . ., 9 < < ≤ 10 armazenando-os em um vetor p que deve ser impresso pelo seu programa.
Questão 4. Em métodos numéricos pode-se demonstrar que o método iterativo de Jacobi para solucionar um
sistema linear da forma Gx = b com # equações e # incógnitas converge se a matriz G for diagonalmente
dominante, ou seja,
|�88 | >
#∑
9=1, 9≠8
|�8 9 |, ,∀8 ∈ 0, 2, . . . , # − 1.
Em outras palavras, para cada linha de G o módulo do elemento da diagonal deve ser maior que a soma dos
módulos dos elementos fora da diagonal. Escreva uma função bool isDiagDom(float *A, const short N)
que recebe por referência uma matriz A com N linhas e N colunas. A função isDiagDom deve retorna true se A
for diagonalmente dominante e false caso contrário. Na função main, crie uma matriz B com N = 3 linhas e
colunas e leia a mesma via teclado. Em seguida, utilize a função isDiagDom para determinar se a matriz B é ou
não diagonalmente dominante e imprima uma mensagem adequada em cada caso. O módulo de um número
real pode ser obtido usando a função fabs da biblioteca cmath.