Home > Net >  Creating 'n' students from a student class. C
Creating 'n' students from a student class. C

Time:06-27

I'm practicing C on HackerRank and came across this problem. I created the class pretty well but struggled to create n student objects I can work with correctly. I searched for similar problems (this is an example) but could not find help, then I came across this solution. It worked well, but I honestly don't understand what exactly happened in line 37 of the solution. I went to cppinsights.io to see for myself and got the output below.

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

class Student
{
  
  public: 
  inline void input()
  {
    for(int i = 0; i < 5;   i) {
      std::cin.operator>>(this->scores[i]);
    }
    
  }
  
  inline int total_score()
  {
    int sum = 0;
    for(int i = 0; i < 5;   i) {
      sum = (sum   this->scores[i]);
    }
    
    return sum;
  }
  
  
  private: 
  int scores[5];
  public: 
  // inline constexpr Student() noexcept = default;
};



int main()
{
  int n;
  std::cin.operator>>(n);
  Student * s = new Student []();
  for(int i = 0; i < n;   i) {
    s[i].input();
  }
  
  int kristen_score = s[0].total_score();
  int count = 0;
  for(int i = 1; i < n;   i) {
    if(s[i].total_score() > kristen_score) {
      count  ;
    } 
    
  }
  
  std::cout.operator<<(count).operator<<(std::endl);
  return 0;
}

Can someone help me explain Student *s = new Student[n];?

How would I do it if my class has a parameterized constructor taking student name or ID as argument. I'm asking this because this problem assumes Kristen's scores to be the first input all the time, but I'd like to compare any student with his peers. Thank you.

CodePudding user response:

I figured I should write some code to give you an example of how to use a std container.

class Student
{
    std::vector<int> scores;
    std::string name;
    int id;

public:
    Student()
    {
        name = "No name";
        id = 0;
    }
    Student(std::string studentName, int identifier)
    : name(studentName), id(identifier) {}


    const char* getName() const {return name.c_str(); }
    int getId() const { return id; }

    int getTotalScore() const{
        int total = 0;
        for(auto& score : scores){
            total  = score;
        }
        return total;
    }

    void addScore(int score)
    {
        scores.emplace_back(score);
    }

};

int main()
{
    std::vector<Student> students;
    //Lets not reallocate 5 times
    students.reserve(5);

    for(int i = 0; i < 5; i  )
    {
        std::string name = "Student";
        name  = std::to_string(i);

        students.emplace_back(name, i);
        for (int j = 0; j < 3; j  ) {
            students[i].addScore((i   1) * 5);
        }
    }

    for(auto& student : students)
    {
        std::cout << "Name: " << student.getName() << " id: " << student.getId() << " Total score: " << student.getTotalScore() << std::endl;
    }
}

You can see the student class has two constructors one with and without arguments, so you can make either of these.

I don't recommend allocating on the heap (using the "new" keyword), until you are a bit more experienced in C . Try learn the standard containers first std::string, std::vector, std::Array, etc.

In this example I use standard vector. emplace_back calls the constructor for student and places it in the vector, who will manage that memory for me.

Note I reserve 5 before I place students into it because every time the vector needs to get longer it will copy every element, so is best to avoid this. I.e. When I place the 6th element it would have to create 5 copies and 1 new object.

The other things can can be seen in this code that you should learn on your C journey are:

  • Initalizer lists: https://www.geeksforgeeks.org/when-do-we-use-initializer-list-in-c/
  • "const" keyword
  • Lastly you notice I don't put std::cin into the Student class. Student class should not know about the input method. This is called encapsulation. This is one of the most important things to learn as a software developer (Which might be ignoring the question, but that just means the architect was poor)

You can link this into the input function.

Bonus questions what if I type "afdasf" into the console, will your application crash? what if I type no characters, and just press enter?

CodePudding user response:

Here's my solution that passes all test cases:

#include <array>
#include <numeric>
// Write your Student class here
class Student {
public:
    Student() = default;
    
    void input() {
        for (int i = 0; i < 5;   i) {
            std::cin >> m_scores[i];
        }
    }
    
    int calculateTotalScore() const {
        return std::accumulate(m_scores.begin(), m_scores.end(), 0);
    }
    
private:
    std::array<int, 5> m_scores{0};
};

It's known ahead of time how many scores there are, so an array makes more sense. The total is calculated using a Standard Library function, std::accumulate().

Line 37 is part of the problem, not the solution, because you didn't write it and can't change it. But all it does is allocate an array on the heap. If that line is throwing you, I highly recommend using a good book to learn, and not one of these competitive coding sites. Hackerrank (and pretty much all sites of this kind) problems are rife with issues and poor practices and poor requirements. What it might teach you is not good to learn. These sites are meant to be used for fun after you know what you're doing.

Caring about anything beyond meeting the requirements is over-engineering. Apply YAGNI when solving a problem, especially from these sites.

  • Related