我在HackerRank上练习c++,遇到了这个问题。我很好地创建了这个类,但很难创建n个我可以正确使用的学生对象。我搜索了类似的问题(这是一个例子),但找不到帮助,然后我遇到了这个解决方案。它工作得很好,但老实说,我不明白解决方案的第37行到底发生了什么。我自己去cppinsights.io
看看,得到了下面的输出:
#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;
}
谁能帮我解释一下Student *s = new Student[n];
?
如果我的类有一个以学生姓名或ID作为参数的参数化构造函数,我该如何做呢?我之所以问这个问题,是因为这个问题假设克里斯汀的分数一直是第一输入,但我想把任何一个学生与他的同龄人进行比较。谢谢你。
这是我通过所有测试用例的解决方案:
#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};
};
预先知道有多少分数,所以数组更有意义。使用标准库函数std::accumulate()
计算总数。
第37行是问题的一部分,而不是解决方案,因为它不是你写的,也不能改变它。但它所做的只是在堆上分配一个数组。如果这句话让您感到困惑,我强烈建议您使用一本好书来学习,而不是使用这些竞争激烈的编码网站。Hackerrank(以及几乎所有这类网站)的问题充斥着各种问题、糟糕的实践和糟糕的需求。它可能教给你的东西是不好学的。这些网站的目的是在你知道你在做什么之后用来娱乐。
关心任何超出满足需求的事情都是过度工程。在解决问题时应用YAGNI,特别是从这些站点。
我想我应该写一些代码给你一个如何使用std容器的例子。
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;
}
}
您可以看到student类有两个构造函数,一个带参数,一个不带参数,因此您可以创建其中任何一个。
我不建议在堆上分配(使用"new"关键字),直到你对c++更有经验。试着先学习标准容器std::string, std::vector, std::Array等。
在这个例子中,我使用标准向量。Emplace_back调用student的构造函数并将其放入vector中,vector将为我管理该内存。
注意,在放入学生之前我保留了5,因为每次向量需要变长时,它都会复制每个元素,所以最好避免这样做。例如,当我放置第6个元素时,它必须创建5个副本和1个新对象。
在这段代码中可以看到的其他东西,你应该在你的c++之旅中学习:- 初始化列表:https://www.geeksforgeeks.org/when-do-we-use-initializer-list-in-c/
- "const"关键字 最后,您注意到我没有将std::cin放入Student类中。学生班不应该知道输入法。这就是所谓的封装。这是作为软件开发人员要学习的最重要的事情之一(这可能忽略了这个问题,但这只意味着架构师很差)
您可以将此链接到输入函数中。
奖金问题如果我输入"afdasf"进入控制台,您的应用程序会崩溃吗?如果我不输入任何字符,只按回车键呢?