Ir ao conteúdo

C++ dificuldade com programa envolvendo vetor como estrutura


Posts recomendados

Postado

"A interface de um TAD que representa um estudante já foi definida. Como atributos esse TAD possui o nome, número de matrícula e notas.Escreva um programa que lê as informações de exatamente 10 alunos como entrada e os salva em um vetor. Em seguida, ele deve escrever na saída a matrícula, nome e o RSG dos três melhores alunos de forma ordenada pelo RSG (do maior para o menor). Em caso de empate, selecione o que possuir a menor matrícula." A parte em que faço um novo vetor (melhores[3]) e associo ao aux 9/8/7 esta dando errado. Ainda não fiz a parte em que há empate de matricula, também estou com dificuldade;

 

meu código ficou assim (só a parte do main, em que estou tendo problemas): 

 

#include <iostream>
#include "Estudante.hpp"

  int main () {
    
    Estudante alunos[10]; int aux=0; Estudante melhores[3];
      
    for (int i=0; i<10; i++){
    cin >> alunos.matricula;
    cin >> alunos.nome;
    for (int j=0; j<5; j++){
        cin >> alunos.notas[j];
    }
    
} 

    
    for (int i=0; i<10; i++){
        alunos.calcularRSG();
    }
    
 
    
    for (int i=0; i<10; i++){
        for (int j=0; j<10; j++){
        if (alunos.calcularRSG() > alunos[j].calcularRSG()){
        aux++;
        }
        else;
      }
      aux= 0; 
      if (aux=9)==melhores[0];
      else if (aux=8)==melhores[1];
      else if (aux=7)==melhores[2];
    }
   
        cout << melhores[0].matricula << " ";
        cout << melhores[0].nome << " ";
        cout << setprecision(2) << melhores[0].calcularRSG();
  
        cout << melhores[1].matricula << " ";
        cout << melhores[1].nome << " ";
        cout << setprecision(2) << melhores[1].calcularRSG();
   
        cout << melhores[2].matricula << " ";
        cout << melhores[2].nome << " ";
        cout << setprecision(2) << melhores[2].calcularRSG();


    return 0; 
}

 

Postado

image.png.719fa4e7d5adbc21b8b80e02a11e58c6.png

 

alunos é um vetor de Estudante. Como acha que o programa vai saber em qual dos 10 Estudante vai ler a matrícula, por exemplo? Simples: com o índice. Só que você não passou o índice na leitura.

 

Curiosamente logo depois passou, na hora de ler as notas...

 

Qual a matricula do terceiro aluno? alunos[2].matricula

 

6 horas atrás, clararezende disse:

só a parte do main, em que estou tendo problemas

 

Se você não postar o programa todo quem vai ter problemas serei eu ou qualquer um que queira te ajudar... Poste algo que a gente possa compilar sem ter que criar novos dados ou inventar trechos de programa....

 

Sempre que o enunciado permitir, LEIA DE UM ARQUIVO. É muito mais fácil. 

E não requer a paciência de digitar dados e mais dados: você só digita o arquivo no próprio IDE e pode usar recortar e colar e tal... Pense nisso

 

  • Curtir 1
Postado
#ifndef ESTUDANTE_H
#define ESTUDANTE_H

#include <string>

struct Estudante {
  std::string nome;
  int matricula;
  float notas[5];

  float calcularRSG();
};

#endif

esse é o arquivo hpp. Aqui está minha funçao calcular.RSG
 

#include <iostream>
#include "Estudante.hpp"

using namespace std;

float calcularRSG(){
    float media=0.00;
    float soma=0.00;
    float notas[5];
    for (int i=0; i<5; i++){
        soma+=notas[i];
    }
    media = soma/5;
    return media;
}

 

Postado

Entendeu o que eu te expliquei sobre os índices que estão faltando?

 

13 horas atrás, arfneto disse:

alunos é um vetor de Estudante. Como acha que o programa vai saber em qual dos 10 Estudante vai ler a matrícula, por exemplo? Simples: com o índice. Só que você não passou o índice na leitura.

 

Curiosamente logo depois passou, na hora de ler as notas...

 

Qual a matricula do terceiro aluno? alunos[2].matricula

 

Corrija e poste o novo código se ainda não estiver ok

Postado

Entendi sim!! Inclusive já tinha colocado, não sei por que não apareceu.
 

#include<iostream>
#include<iomanip>
#include "Estudante.hpp"

using namespace std;

int main(){
    
    Estudante alunos[10]; int aux=0; Estudante melhores[3];
    
    //inicializando o vetor alunos
    
    for (int i=0; i<10; i++){
    cin >> alunos[i].matricula;
    cin >> alunos[i].nome;
    for (int j=0; j<5; j++){
        cin >> alunos[i].notas[j];
    }
    
} 

    // media 
    for (int i=0; i<10; i++){
        alunos[i].calcularRSG();
    }
    
    
    //pegando as maiores medias
    
    for (int i=0; i<10; i++){
        
        for (int j=1; j<10; j++){
            
        if (alunos[i].calcularRSG() > alunos[j].calcularRSG()){
        aux++;}
        }
        }
        
      }
      if (aux==9) = melhores[0];
      else if (aux==8) = melhores[1];
      else if (aux==7) = melhores[2];
    }
   
        cout << melhores[0].matricula << " ";
        cout << melhores[0].nome << " ";
        cout << setprecision(2) << melhores[0].calcularRSG();
  
        cout << melhores[1].matricula << " ";
        cout << melhores[1].nome << " ";
        cout << setprecision(2) << melhores[1].calcularRSG();
   
        cout << melhores[2].matricula << " ";
        cout << melhores[2].nome << " ";
        cout << setprecision(2) << melhores[2].calcularRSG();


    return 0; 
}
    
    

Não sei se meu código ficou muito claro, não tenho muita facilidade com programação. Mas minha ideia para pegar os melhores alunos foi de comparar cada um com o próximo, e assim somar um no auxiliar. Se um aluno tiver media maior do que 9 pessoas, será o melhor da turma, o que tiver media maior do que 8, seria o segundo, e assim para o terceiro. Não estou conseguindo passar essa ideia pro código. Desculpa se está confuso!! 

Postado
12 minutos atrás, clararezende disse:

Mas minha ideia para pegar os melhores alunos foi de comparar cada um com o próximo, e assim somar um no auxiliar. Se um aluno tiver media maior do que 9 pessoas, será o melhor da turma, o que tiver media maior do que 8, seria o segundo, e assim para o terceiro. Não estou conseguindo passar essa ideia pro código. Desculpa se está confuso!!

 

Não é uma ideia ruim eu acho. Mas eu acho mais fácil pensar em quantos tem média maior que a de um cara. Se ninguém tem ele é o melhor, se 1 tem ele é o segundo, se 2 tem ele é o terceiro melhor...

 

E não é comparar cada um com o próximo mas sim comparar cada um com todos os outros. Isso é o selection sort, apenas para 3 iterações.

 

Sobre o resto do código, entenda que se trata de C++ então é mais simples pensar que a média é uma função da classe Estudante. um método. É muito mais fácil. 

 

E claro que já que estamos falando nisso a classe Estudante poderia ser aumentada para incluir a média já calculada

 

E uma classe Turma seria um grupo de Estudantes.

Postado

Pois é, eu pensei em comparar um com todos os outros mas não estou conseguindo colocar isso dentro do programa. Nunca ouvi falar de selection sort. 

1 hora atrás, arfneto disse:

Sobre o resto do código, entenda que se trata de C++ então é mais simples pensar que a média é uma função da classe Estudante. um método. É muito mais fácil.

Sobre isso, não entendi muito bem como deveria chamar a minha função média. Perdão por não entender rápido, estou estudando c++ faz apenas duas semanas, e não tive uma base boa em c, por isso estou tendo bastante dificuldade!

Postado
25 minutos atrás, clararezende disse:

não entendi muito bem como deveria chamar a minha função média. Perdão por não entender rápido, estou estudando c++ faz apenas duas semanas, e não tive uma base boa em c

 

Nesses casos não há qualquer equivalente em C então não teria ajudado. Talvez tivesse sido muito melhor aprender C++ primeiro e depois usar C para aplicações especiais. Mas é só um palpite. Muita gente concorda comigo no entanto.

 

Em C++ é muito mais fácil criar modelos de coisas e abstrair modelos concretos.

 

Exemplo

 

Veja a classe Estudante: Uma classe Turma podia ter um grupo de estudantes, e ter uma função que lê os estudantes a partir de um arquivo, e outra que mostra os 3 melhores de uma certa Turma.

 

E assim seu programa estaria pronto

 

Classe Turma, mínima

class Turma
{
public:
	Estudante aluno[10];
public:
	Turma(string arquivo){};	// Turma()
	void Mostra_3_mais() {};
	void Mostra_turma();
};

Entenda que uma Turma pode ser mais ou menos complexa, mas aqui é apenas um grupo de 10 Estudante.

No entanto

  • tem uma função Mostra_3_mais() que vai listar os 3 melhores como o enunciado pede
  • tem uma função Mostra_turma() para mostrar na tela a Turma só pra tirar qualquer dúvida se leu certo
  • e Turma() é uma função especial, chamada construtor, que tem o nome da classe, Turma. E nesse caso é a única maneira de criar uma Turma, escrevendo por exemplo
        Turma("alunos.txt"); 

    e imaginando que tal função vai abrir o arquivo e ler os 10 alunos.

Funções são chamadas métodos nesse contexto em C++ ou java.
 

Entenda que ANTES mesmo de escrever o programa os dados e funções se ajustam e tem comportamentos, e tudo é muito mais fácil. Parece que se pode escrever

	Turma A("alunos.txt");
	Turma B("nova_turma.txt");
	Turma teste("outros.txt");

E criar e manter 3 turmas distintas. E é isso mesmo

 

A classe Estudante

class Estudante
{
public:
	string	nome;
	int	matricula;
	float	notas[5];

public:
	float calcularRSG()
	{
		float soma = 0.00;
		for (int i = 0; i < 5; i++) soma += notas[i];
		return soma / 5.0f;
	};
};

Esse estudante tem uma função, um método que calcula a média. Veja como criar um Estudante e calcular a media dele:

	Estudante modelo;
	modelo.nome = "Johnny Cash";
	modelo.matricula = 12345;
	modelo.notas[0] = 1.23f;
	modelo.notas[1] = 4.56f;
	modelo.notas[2] = 7.89f;
	modelo.notas[3] = 2.34f;
	modelo.notas[4] = 5.67f;
	cout << "Media para o aluno modelo " <<
		modelo.calcularRSG() << endl;

Agora e se eu criar uma Turma e copiar esse modelo para os 10 alunos só para testar o programa? Não seria confortável? E talvez trivial? Sim. É mesmo.

	Turma A("alunos.txt");
	for (auto i = 0; i < 10; i += 1)
		A.aluno[i] = modelo;
	A.Mostra_turma();

Isso aí vai criar a Turma A a partir do arquivo "alunos.txt". Só que a gente nem escreveu isso ainda. Então vamos pegar o aluno modelo e copiar para preencher os 10 alunos da turma A.

 

E mostrar na tela. Mostrar é só um cout:

void Turma::Mostra_turma()
{
	for (auto A : aluno)
	{
		cout << "Nome: " << A.nome <<
			" Matricula: " << A.matricula <<
			endl;
		for (auto N : A.notas)
			cout << setprecision(2) << N << " ";
		cout << endl;
	};	// for()
};

O operador '::' indica que a função --- método --- pertence à classe Turma. E não é preciso declarar nada porque a função está DENTRO da classe Turma então tem acesso a tudo.

 

Leia esse programa e vai entender melhor

#include <iomanip>
#include <iostream>
using namespace std;

class Estudante
{
public:
	string	nome;
	int		matricula;
	float	notas[5];

public:
	float calcularRSG()
	{
		float soma = 0.00;
		for (int i = 0; i < 5; i++) soma += notas[i];
		return soma / 5.0f;
	};
};

class Turma
{
public:
	Estudante aluno[10];
public:
	Turma(string arquivo){};	// Turma()
	void Mostra_3_mais() {};
	void Mostra_turma();
};

int main(int argc, char** argv)
{
	Estudante modelo;
	modelo.nome = "Johnny Cash";
	modelo.matricula = 12345;
	modelo.notas[0] = 1.23f;
	modelo.notas[1] = 4.56f;
	modelo.notas[2] = 7.89f;
	modelo.notas[3] = 2.34f;
	modelo.notas[4] = 5.67f;
	cout << "Media para o aluno modelo " <<
		modelo.calcularRSG() << endl;

	Turma A("alunos.txt");
	for (auto i = 0; i < 10; i += 1)
		A.aluno[i] = modelo;

	A.Mostra_turma();
}


void Turma::Mostra_turma()
{
	for (auto A : aluno)
	{
		cout << "Nome: " << A.nome <<
			" Matricula: " << A.matricula <<
			endl;
		for (auto N : A.notas)
			cout << setprecision(2) << N << " ";
		cout << endl;
	};	// for()
};

Ele mostra

Media para o aluno modelo 4.338
Nome: Johnny Cash Matricula: 12345
1.2 4.6 7.9 2.3 5.7
Nome: Johnny Cash Matricula: 12345
1.2 4.6 7.9 2.3 5.7
Nome: Johnny Cash Matricula: 12345
1.2 4.6 7.9 2.3 5.7
Nome: Johnny Cash Matricula: 12345
1.2 4.6 7.9 2.3 5.7
Nome: Johnny Cash Matricula: 12345
1.2 4.6 7.9 2.3 5.7
Nome: Johnny Cash Matricula: 12345
1.2 4.6 7.9 2.3 5.7
Nome: Johnny Cash Matricula: 12345
1.2 4.6 7.9 2.3 5.7
Nome: Johnny Cash Matricula: 12345
1.2 4.6 7.9 2.3 5.7
Nome: Johnny Cash Matricula: 12345
1.2 4.6 7.9 2.3 5.7
Nome: Johnny Cash Matricula: 12345
1.2 4.6 7.9 2.3 5.7

Nesse exemplo você poderia ir direto escrever e testar a função

     void Mostra_3_mais(){}; 

porque afinal já tem uma Turma pronta para testar a classificação...

 

Espero que tenha entendido o poder desses conceitos em torno de Classes, apesar de ser só um exemplo bobinho.

 

Você tem um livro? Seu curso adota um livro-texto?

 

Postado

Nossa!! Mil desculpas pela demora, estava fazendo outras matérias. Me ajudou demais! Eu estou usando o livro "Think C++" do Allen B. Downey, está em inglês mas está me ajudando bastante. Acho que agora vou conseguir fazer! Muito obrigada!

Postado

Mostrar os N melhores alunos pode ser bem bobinho, como usar Selection Sort. Esse é o modo mais ingênuo de classificar as coisas, o que uma criança faria pra por em ordem umas coisas da menor para a maior por exemplo: Tem 20 coisas: olha uma a uma e escolhe a menor. Depois faz a mesma coisa com as 19 que sobraram. E com as 18. Está feita sua função: encontrou os 3 melhores alunos. Por exemplo:

void Turma::Mostra_3_mais()
{
	// para os primeiros 3 compara com todos e coloca
	// o que tem a maior media na frente
	for (auto al = 0; al < 3; al += 1)
	{
		for (auto outro = al + 1; outro < 10; outro += 1)
		{
			if (compara_alunos(aluno[al], aluno[outro]) > 0)
			{
				Estudante temp = aluno[al];
				aluno[al] = aluno[outro];
				aluno[outro] = temp;
			};	// if()
		};	// for()
	};	// for()
	// mostra os 3 afinal
	for (auto al = 0; al < 3; al += 1)
	{
		cout << "'" << aluno[al].nome <<
			"' Mat #" << setw(6) << aluno[al].matricula <<
			" Notas [ ";
		for (auto N : aluno[al].notas)
			cout << setw(6) << setprecision(4) << N << " ";
		cout << "] Media = " << aluno[al].media() << endl;
	};	// for()
};	// Mostra_3_mais()

compara_alunos() não é uma ideia eficiente: é só pra ficar fácil de ler o código nesse exemplo. E não é nada sofisticado:

int		Turma::compara_alunos(Estudante& um, Estudante& outro)
{
	// retorna 1 se um menor que outro :) 
	if (um.media() > outro.media()) return -1;
	if (um.media() < outro.media()) return 1;
	return um.matricula > outro.matricula;
};

Mas funciona. 

 

Se trocar o 3 pelo tamanho do grupo (menos 1 porque a comparação precisa de dois) vai classificar os alunos todos. Selection Sort.

Postado

Esqueci de comentar, mas é claro que está classificando o próprio vetor de alunos. Não há razão para criar outro lugar e só iria complicar as coisas: Alunos[10] não serve para nada depois então é claro que é mais fácil começar a por o vetor em ordem, mas parar no terceiro.
 

E é claro que o segundo loop, que mostra o resultado, é copiado da função que mostra todos...

Postado

Consegui fazer tudo certinho aqui! A única coisa que está dando errado é que a média não está saindo com duas casas decimais, não entendi por quê, como na hora de fazer a funçao calcularRSG() estou usando tudo com duas casas decimais.

 

Postado

Estou tendo outro problema... quando a media empata, tenho que retornar primeiro o que tem a menor matrícula. Na função Compara_aluno, quando coloco o "return um.matricula < dois.matricula" isso ocorre, porém o output para de aparecer na ordem da média, e sim de matrícula. Porém quando coloco "return um.matricula > dois.matricula" quando há empate de média, ele mostra quem tem matricula maior primeiro. 

adicionado 3 minutos depois

Consegui consertar o problema das matriculas! Das decimais não.

adicionado 26 minutos depois

Consegui!!!! coloquei << setprecision (2) << fixed << aluno.media() e deu certo! Não tenho palavras para agradecer. Consegui entender tudo!!!

Postado

Muito bom que conseguiu! Espero que tenha entendido melhor a ideia das tais classes e métodos e tal.

 

Vou deixar o exemplo que eu estava usando. Pode ser útil ainda.

 

O programa lê o arquivo "alunos.txt". Claro, pode ser qualquer um:

int main()
{
    Turma T("alunos.txt");
    T.Mostra_turma();
    cout << "\n\n 3 \n\n";
    T.Mostra_3_mais();
};

E na prática o nome do arquivo deveria vir direto na linha de comando.

 

Para esse arquivo

aluno  1,1123,1.1,2.22,3.333,4.4,5.5
aluno  2,2323,6,7,8,9,10
aluno  3,54545,11,12,13,14,15
aluno  4,456464,16,17,18,19,20
aluno  5,5656,21,22,23,24,25
aluno  6,343,26,27,28,29,30
aluno  7,344,26,27,28,29,30
aluno  8,345,26,27,28,29,30
aluno  9,346,26,27,28,29,30
aluno 10,347,26,27,28,29,30.2

O Programa mostra

'aluno  1' Mat #  1123 Notas [    1.1   2.22  3.333    4.4    5.5 ] Media = 3.311
'aluno  2' Mat #  2323 Notas [      6      7      8      9     10 ] Media = 8
'aluno  3' Mat # 54545 Notas [     11     12     13     14     15 ] Media = 13
'aluno  4' Mat #456464 Notas [     16     17     18     19     20 ] Media = 18
'aluno  5' Mat #  5656 Notas [     21     22     23     24     25 ] Media = 23
'aluno  6' Mat #   343 Notas [     26     27     28     29     30 ] Media = 28
'aluno  7' Mat #   344 Notas [     26     27     28     29     30 ] Media = 28
'aluno  8' Mat #   345 Notas [     26     27     28     29     30 ] Media = 28
'aluno  9' Mat #   346 Notas [     26     27     28     29     30 ] Media = 28
'aluno 10' Mat #   347 Notas [     26     27     28     29   30.2 ] Media = 28.04


 3

'aluno 10' Mat #   347 Notas [     26     27     28     29   30.2 ] Media = 28.04
'aluno  6' Mat #   343 Notas [     26     27     28     29     30 ] Media = 28
'aluno  7' Mat #   344 Notas [     26     27     28     29     30 ] Media = 28

O programa

#include <string>
#include <iomanip>
#include <iostream>
#include <istream>

using namespace std;

class Estudante
{
public:
    string	nome;
    int		matricula;
    float	notas[5];

public:
    float media()
    {
        float soma = 0.00;
        for (int i = 0; i < 5; i++) soma += notas[i];
        return soma / 5.0f;
    };
}; 

class Turma
{
public:
	Estudante aluno[10];
public:
	Turma(string);

	int		compara_alunos(Estudante&, Estudante&);
	void	Mostra_3_mais();
	void	Mostra_turma();
};

int main()
{
    Turma T("alunos.txt");
    T.Mostra_turma();
    cout << "\n\n 3 \n\n";
    T.Mostra_3_mais();
};

// a unica maneira aqui de criar uma turma e atraves
// de um arquivo com os 10 alunos
Turma::Turma(string arquivo)
{
	FILE* entrada = fopen(arquivo.c_str(), "r");
	char nome[50];
	int delim = 0;
	// formato obvio:
	// nome,matricula,5 notas. tudo separado por
	// virgulas, um aluno por linha: CSV
	const char* mascara =
		"%[^,],%d,%f,%f,%f,%f,%f%[\n]";
	for (auto i = 0; i < 10; i += 1)
	{
		memset(nome, 0, sizeof(nome));
		int res = fscanf(entrada, mascara,
			nome, &aluno[i].matricula,
			&aluno[i].notas[0], &aluno[i].notas[1],
			&aluno[i].notas[2], &aluno[i].notas[3],
			&aluno[i].notas[4], &delim);
		if (res < 8)
		{
			cerr << "Erro no arquivo " << arquivo << endl;
			exit(-1);
		}
		aluno[i].nome = nome;
	};
};	// Turma()

int		Turma::compara_alunos(Estudante& um, Estudante& outro)
{
	// retorna 1 se um menor que outro :) 
	if (um.media() > outro.media()) return -1;
	if (um.media() < outro.media()) return 1;
	return um.matricula > outro.matricula;
};

void Turma::Mostra_3_mais()
{
	// para os primeiros 3 compara com todos e coloca
	// o que tem a maior media na frente
	for (auto al = 0; al < 3; al += 1)
	{
		for (auto outro = al + 1; outro < 10; outro += 1)
		{
			if (compara_alunos(aluno[al], aluno[outro]) > 0)
			{
				Estudante temp = aluno[al];
				aluno[al] = aluno[outro];
				aluno[outro] = temp;
			};	// if()
		};	// for()
	};	// for()
	// mostra os 3 afinal
	for (auto al = 0; al < 3; al += 1)
	{
		cout << "'" << aluno[al].nome <<
			"' Mat #" << setw(6) << aluno[al].matricula <<
			" Notas [ ";
		for (auto N : aluno[al].notas)
			cout << setw(6) << setprecision(4) << N << " ";
		cout << "] Media = " << aluno[al].media() << endl;
	};	// for()
};	// Mostra_3_mais()

void Turma::Mostra_turma()
{
	for (auto A : aluno)
	{
		cout << "'" << A.nome <<
			"' Mat #" << setw(6) << A.matricula <<
			" Notas [ ";
		for (auto N : A.notas)
			cout << setw(6) << setprecision(4) << N << " ";
		cout << "] Media = " << A.media() << endl;
	};	// for()
};


// https://www.clubedohardware.com.br/forums/topic/
// 1476728-dificuldade-com-programa-envolvendo-vetor-como-estrutura/

 

  • 4 meses depois...
Postado
12 minutos atrás, Lucas Frazão disse:

Queria ver como ficou o programa final do visitante ai, achei interessante o desafio proposto

 

O programa como eu escrevi resolve o "desafio proposto" :D 
 

"Visitante" quer dizer que o usuário "clararesende" já deixou o forum...
 

O resultado deve ser algo como acima, listar os alunos com as 3 melhores médias.
 

3

'aluno 10' Mat #   347 Notas [     26     27     28     29   30.2 ] Media = 28.04
'aluno  6' Mat #   343 Notas [     26     27     28     29     30 ] Media = 28
'aluno  7' Mat #   344 Notas [     26     27     28     29     30 ] Media = 28

 

  • Curtir 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!