Percursos
/
C++
C++
/
Exercícios
/
Passar de ano
Passar de ano

Passar de ano

Exercício de aprendizagem

Introdução

Arrays e vetores

O C++ oferece diferentes contentores para armazenar elementos do mesmo tipo de forma ordenada. Existe o std::array para contentores de tamanho fixo e o std::vector, que vem com capacidades de redimensionamento dinâmico.

Construção

Quando declaras um array ou um vetor, tens de especificar o tipo de elementos que o contentor vai conter. Os arrays também precisam de um tamanho. Vê estes exemplos para ver a inicialização dos dois tipos de contentores:

#include <array>
#include <string>

// std::array<element_type, size> variable_name {list of elements}
std::array<std::string, 3> indie_rock {"yeah", "yeah", "yeah"};
// indie_rock contains the elements "yeah" three times

Os vetores normalmente precisam de mais espaço, pois alocam memória para crescimento futuro. Não precisas de especificar um tamanho:

#include <vector>

// std::vector<element_type> variable_name {list of elements}
std::vector<int> countdown {3, 2, 1};
// countdown contains the elements 3, 2 and 1

Nota: Ainda não precisas de conhecer a mecânica exata por trás do conceito de template, ele terá o seu próprio conceito mais abaixo na árvore do currículo.

Acesso aos elementos

Os vetores e os arrays partilham as mesmas funções para aceder aos seus elementos. Podes usar as funções membro front e back para obter o primeiro e o último elementos do contentor. Existe também a at e o operador [] para aceder a elementos específicos.

countdown[0];
// => 3
countdown.at(2);
// => 1
countdown[1] = 4;
// countdown now contains 3, 4 and 1
indie_rock.back() = "yeahs";
// indie_rock is now "yeah", "yeah", "yeahs"

Nota: Se escolheres uma posição que não está no intervalo do teu contentor, o [] pode levar a comportamento indefinido. A função at lançaria uma exceção, o que pode tornar a tua vida mais fácil a longo prazo.

Modificadores de vetores

Como um vector não tem tamanho fixo, é possível adicionar ou remover elementos. Duas funções comuns para esse efeito são emplace_back e pop_back.

std::vector<std::string> witches {"Holly", "Alyssa", "Shannen"};
witches.pop_back();
// Shannen is no longer with the witches
witches.emplace_back("Rose");
// Rose has joined the team

Capacidade

Podes verificar se os contentores estão vazios com a função membro empty. Se quiseres saber o número de elementos, podes usar size.

Instruções

És assistente de ensino e estás a corrigir exames de alunos. Manter o registo dos resultados à mão está a tornar-se maçador e propenso a erros. Decides tornar as coisas um pouco mais interessantes criando algumas funções para contar e calcular os resultados da turma.

1. Arredondar as pontuações

Embora possas dar "crédito parcial" nas perguntas do exame, as pontuações globais do exame têm de ser ints. Por isso, antes de fazeres mais alguma coisa com as pontuações da turma, tens de percorrer as classificações e converter todas as pontuações double em ints.

Cria a função round_down_scores() que recebe um vector de student_scores. O arredondamento pedido pelas escolas é um truncamento. Felizmente para ti, o C++ consegue converter um tipo noutro com static_cast. A conversão static_cast de double para int corta todos os algarismos a seguir à vírgula. Esta função deve receber o vector de entrada e return um novo vetor com todas as pontuações convertidas em ints.

std::vector<double> student_scores {90.33, 40.5, 55.44, 70.05, 30.55, 25.45, 80.45, 95.3, 38.7, 40.3};
round_down_scores(student_scores)
// => {90, 40, 55, 70, 30, 25, 80, 95, 38, 40}

Há outros métodos que alcançam o mesmo resultado, mas um cast é algo que se vê com frequência.

int new_PI{static_cast<int>(3.14) + static_cast<int>(0.001592653589)};
// new_PI is 3.

2. Alunos que não passam

Enquanto estavas a classificar o exame, reparaste que alguns alunos não estavam a ter o desempenho que esperavas. Mas distraíste-te e esqueceste-te de anotar exatamente quantos alunos.

Cria a função count_failed_students() que recebe um vector de student_scores. Esta função deve contar o número de alunos que não têm pontuação de aprovação e devolver essa contagem como um número inteiro. Um aluno precisa de uma pontuação superior a 40 para ter nota de aprovação no exame.

count_failed_students({90,40,55,70,30,25,80,95,38,40});
// => 5

3. Calcular as notas por letras

O professor a quem assistes gosta de atribuir notas por letras, além de pontuações numéricas. Como é raro os alunos tirarem 100 num exame, os limites inferiores da "nota por letras" são calculados com base na pontuação mais alta alcançada e aumentam de forma uniforme entre a pontuação mais alta e o limite de reprovação de <= 40.

Cria a função letter_grades() que recebe a pontuação "mais alta" do exame como parâmetro e devolve um array (não um vetor) de limites inferiores de pontuação para cada intervalo de nota "à americana": ["D", "C", "B", "A"].

/*Where the highest score is 100, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 55
 56 <= "C" <= 70
 71 <= "B" <= 85
 86 <= "A" <= 100
*/

letter_grades(100);
// => {41, 56, 71, 86}


/*Where the highest score is 88, and failing is <= 40.
       "F" <= 40
 41 <= "D" <= 52
 53 <= "C" <= 64
 65 <= "B" <= 76
 77 <= "A" <= 88
*/

letter_grades(88);
// => {41, 53, 65, 77}

4. Associar nomes a pontuações

Tens as pontuações do exame por ordem decrescente e os respetivos nomes dos alunos (ordenados pela ordem das suas pontuações no exame). Gostarias de associar o nome de cada aluno à sua pontuação no exame e imprimir uma classificação geral da turma.

Cria a função student_ranking() com os parâmetros student_scores e student_names. Associa cada nome de aluno no vector student_names à respetiva pontuação no vector student_scores. Podes assumir que cada vector de argumentos está ordenado da pontuação mais alta para a mais baixa. A função deve devolver um vector de strings com o formato <rank>. <student name>: <student score>.

std::vector<int> student_scores {100, 99, 90, 84, 66, 53, 47};
std::vector<std::string> student_names {"Joci", "Sara","Kora","Jan","Indra","Bern", "Fred"};
student_ranking(student_scores, student_names)
// =>
//  {"1. Joci: 100", "2. Sara: 99", "3. Kora: 90", "4. Jan: 84", "5. Indra: 66", "6. Bern: 53", "7. Fred: 47"}

5. Uma pontuação "perfeita"

Embora uma pontuação "perfeita" de 100 seja rara num exame, é interessante saber se pelo menos um aluno a alcançou.

Cria a função perfect_score() com os parâmetros student_scores e student_names. As listas são as mesmas da tarefa 4. A função deve return o primeiro <name> (como string) do aluno que tirou 100 no exame.

Se não houver pontuações de 100, deve ser devolvida uma string vazia "".

perfect_score({"Nur", "Tony", "Fatima"}, {90, 80, 100});
// => "Fatima"

perfect_score({"Nur", "Tony"}, {90, 80});
// => ""
Editar via GitHub A ligação abre numa nova janela ou separador
C++ Exercism

Estás pronto para começar Passar de ano?

Inscreve-te no Exercism para aprenderes e dominares C++ com 19 conceitos100 exercícios, e mentoria humana real, tudo grátis.