如何在具有动态内存分配的结构中按 cgpa 的降序对数据进行排序?
How to sort data in decreasing order of cgpa in structure with dynamic memory allocation?
结构和 DMA。我想以 cgpa 的降序检索所有插入的记录。
如果不排序,它会给出如下图所示的结果。
#include<iostream>
#include<string>
using namespace std;
struct student {
string name;
int age;
float cgpa;
};
void main()
{
student *ptr;
int size;
cout << "enter size \n";
cin >> size;
ptr = new student[size];
for (int i = 0; i < size; i++)
{
cout << "enter student " << i + 1 << " name\n";
cin >> ptr[i].name;
cout << "enter student " << i + 1 << " age\n";
cin >> ptr[i].age;
cout << "enter student " << i + 1 << " cgpa\n";
cin >> ptr[i].cgpa;
}
cout << "with out sorting \n";
for (int i = 0; i < size; i++)
{
cout << " NAME\tAGE\tCGPA\n";
cout << ptr[i].name << "\t" << ptr[i].age << "\t" << ptr[i].cgpa << endl;
}
system("pause");
}
[1]: https://i.stack.imgur.com/whP8d.png
“不排序” 有点不清楚,但我认为这意味着您不能直接调用 std::sort
或使用另一个显式排序例程。这让您可以选择一个容器,该容器根据您提供的比较函数(或重载)按排序顺序存储对象。查看 Microsoft C++ language conformance table for VS2015, it shows all core language features for C++11 supported -- which would include std::set.
std::set
允许您存储一组经过排序的唯一对象。这意味着您可以获取输入并将结果存储在基于您提供的比较函数的 std::set
中。提供比较每个学生的 cgpa
的比较功能将自动存储基于 cgpa
.
的 student
个对象
要使 std::set
可用,您只需 #include<set>
。编写可用于基于 cgpa
存储学生的比较函数只需要为 <
运算符提供重载,该运算符将两个 student
对象作为参数,然后 returns true
当第一个参数排在第二个之前时,false
否则。这可以很简单:
/* overload of < comparing student by cgpa */
bool operator <(const student& a, const student& b) {
return a.cgpa < b.cgpa;
}
注意:除非您正在为没有操作系统的微控制器或嵌入式系统(称为 独立环境)编译,否则 void main()
是错误的。 main()
的标准符合调用是 int main(void)
或 int main (int argc, char **argv)
其中 argc
是 参数计数 和 argv
你的argument vector(技术上是指向空终止字符串的指针数组,其中最后一个参数后的下一个指针设置为 NULL
作为标记)还有其他非标准扩展由一些编译器添加,例如 char **envp
提供指向每个环境变量的指针。
要声明您的 student
组,您需要提供类型 student
以及将学生插入您的组时要使用的比较函数。由于您为小于运算符提供了重载,因此可以使用 std::less<>
提供一个模板参数,例如
int main(void)
{
/* create std::set of students using std::less for compare */
std::set<student, std::less<const student&>> students {};
并且由于您使用的是为您提供自动内存管理的容器,因此无需事先知道 size
(或要输入的学生人数)。您可以根据需要输入任意数量的学生,然后在 Linux 上按 Ctrl+d 或在 [=110 上按 Ctrl+z =] 生成一个手册 EOF
表示您的输入结束。但是,您确实需要通过检查每个输入后的 return(流状态)来 验证 每个用户输入。您至少可以使用:
std::cout << "enter student " << i + 1 << " name\n";
if (!(std::cin >> s.name)) /* validate all input, ctrl + z to end input */
break;
(注意:变量i
只需要提示输入时显示学号,所有容器都提供.size()
成员函数告诉你里面有多少对象。)
完成输入后,您可以使用 Range-based for loop 遍历集合中的每个学生,输出所需的信息。例如:
std::cout << "\nwith out sorting \n";
for (auto& s : students) { /* output in order of cgpa w/o sorting */
std::cout << " NAME\tAGE\tCGPA\n"
<< s.name << "\t" << s.age << "\t" << s.cgpa << '\n';
}
总而言之,你可以这样做:
#include <iostream>
#include <string>
#include <set>
struct student { /* struct student */
std::string name;
int age;
float cgpa;
};
/* overload of < comparing student by cgpa */
bool operator <(const student& a, const student& b) {
return a.cgpa < b.cgpa;
}
int main(void)
{
/* create std::set of students using std::less for compare */
std::set<student, std::less<const student&>> students {};
for (int i = 0; ; i++) {
student s {}; /* temporary struct to add to set */
std::cout << "enter student " << i + 1 << " name\n";
if (!(std::cin >> s.name)) /* validate all input, ctrl + z to end input */
break;
std::cout << "enter student " << i + 1 << " age\n";
if (!(std::cin >> s.age))
break;
std::cout << "enter student " << i + 1 << " cgpa\n";
if (!(std::cin >> s.cgpa))
break;
students.insert(s); /* insert student in set */
}
std::cout << "\nwith out sorting \n";
for (auto& s : students) { /* output in order of cgpa w/o sorting */
std::cout << " NAME\tAGE\tCGPA\n"
<< s.name << "\t" << s.age << "\t" << s.cgpa << '\n';
}
}
(注意: 看看Why is “using namespace std;” considered bad practice?。早点养成好习惯比以后改掉坏习惯要容易得多...)
(注 2: 您可以考虑使用 getline(std::cin, s.name)
来输入学生姓名,这样您就可以处理带空格的姓名,例如 Firstname Lastname
,例如 Mickey Mouse
,由您决定)
重新添加 system("pause");
以保持您的终端 window 根据需要打开。
例子Use/Output
现在只需输入任意数量的学生的学生数据,然后通过生成手动 EOF
如上所述终止输入,例如
$ ./bin/set_student_grades
enter student 1 name
gates
enter student 1 age
20
enter student 1 cgpa
2.12
enter student 2 name
della
enter student 2 age
21
enter student 2 cgpa
2.00
enter student 3 name
jim
enter student 3 age
30
enter student 3 cgpa
3.12
enter student 4 name
with out sorting
NAME AGE CGPA
della 21 2
NAME AGE CGPA
gates 20 2.12
NAME AGE CGPA
jim 30 3.12
这提供了一种按 cgpa
顺序存储和提供学生数据的方法,无需显式 sort
。当然 std::set
会为您做到这一点,但如果避免显式排序是您程序的意图,那么这是一个很好的选择。如果您还有其他问题,请告诉我。
#include<iostream>
#include<string>
using namespace std;
struct student {
string name;
int age;
float cgpa;
};
void main() {
student *ptr;
int size;
cout << "enter size \n"; cin >> size;
ptr = new student[size];
for (int i = 0; i < size; i++)
{
cout << "enter student " << i + 1 << " name\n";
cin >> ptr[i].name;
cout << "enter student " << i + 1 << " age\n";
cin >> ptr[i].age;
cout << "enter student " << i + 1 << " cgpa\n";
cin >> ptr[i].cgpa;
}
string temp1; int temp2; float temp3;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (ptr[i].cgpa < ptr[j].cgpa)
{
temp1 = ptr[j].name;
ptr[j].name = ptr[i].name;
ptr[i].name = temp1;
temp2 = ptr[j].age;
ptr[j].age = ptr[i].age;
ptr[i].age = temp2;
temp3 = ptr[j].cgpa;
ptr[j].cgpa = ptr[i].cgpa;
ptr[i].cgpa = temp3;
}
}
}
for (int i = 0; i < size; i++) {
cout << " NAME\tAGE\tCGPA\n";
cout << ptr[i].name << "\t" << ptr[i].age << "\t" << ptr[i].cgpa << endl;
}
delete[] ptr;
system("pause");
}
结构和 DMA。我想以 cgpa 的降序检索所有插入的记录。 如果不排序,它会给出如下图所示的结果。
#include<iostream>
#include<string>
using namespace std;
struct student {
string name;
int age;
float cgpa;
};
void main()
{
student *ptr;
int size;
cout << "enter size \n";
cin >> size;
ptr = new student[size];
for (int i = 0; i < size; i++)
{
cout << "enter student " << i + 1 << " name\n";
cin >> ptr[i].name;
cout << "enter student " << i + 1 << " age\n";
cin >> ptr[i].age;
cout << "enter student " << i + 1 << " cgpa\n";
cin >> ptr[i].cgpa;
}
cout << "with out sorting \n";
for (int i = 0; i < size; i++)
{
cout << " NAME\tAGE\tCGPA\n";
cout << ptr[i].name << "\t" << ptr[i].age << "\t" << ptr[i].cgpa << endl;
}
system("pause");
}
[1]: https://i.stack.imgur.com/whP8d.png
“不排序” 有点不清楚,但我认为这意味着您不能直接调用 std::sort
或使用另一个显式排序例程。这让您可以选择一个容器,该容器根据您提供的比较函数(或重载)按排序顺序存储对象。查看 Microsoft C++ language conformance table for VS2015, it shows all core language features for C++11 supported -- which would include std::set.
std::set
允许您存储一组经过排序的唯一对象。这意味着您可以获取输入并将结果存储在基于您提供的比较函数的 std::set
中。提供比较每个学生的 cgpa
的比较功能将自动存储基于 cgpa
.
student
个对象
要使 std::set
可用,您只需 #include<set>
。编写可用于基于 cgpa
存储学生的比较函数只需要为 <
运算符提供重载,该运算符将两个 student
对象作为参数,然后 returns true
当第一个参数排在第二个之前时,false
否则。这可以很简单:
/* overload of < comparing student by cgpa */
bool operator <(const student& a, const student& b) {
return a.cgpa < b.cgpa;
}
注意:除非您正在为没有操作系统的微控制器或嵌入式系统(称为 独立环境)编译,否则 void main()
是错误的。 main()
的标准符合调用是 int main(void)
或 int main (int argc, char **argv)
其中 argc
是 参数计数 和 argv
你的argument vector(技术上是指向空终止字符串的指针数组,其中最后一个参数后的下一个指针设置为 NULL
作为标记)还有其他非标准扩展由一些编译器添加,例如 char **envp
提供指向每个环境变量的指针。
要声明您的 student
组,您需要提供类型 student
以及将学生插入您的组时要使用的比较函数。由于您为小于运算符提供了重载,因此可以使用 std::less<>
提供一个模板参数,例如
int main(void)
{
/* create std::set of students using std::less for compare */
std::set<student, std::less<const student&>> students {};
并且由于您使用的是为您提供自动内存管理的容器,因此无需事先知道 size
(或要输入的学生人数)。您可以根据需要输入任意数量的学生,然后在 Linux 上按 Ctrl+d 或在 [=110 上按 Ctrl+z =] 生成一个手册 EOF
表示您的输入结束。但是,您确实需要通过检查每个输入后的 return(流状态)来 验证 每个用户输入。您至少可以使用:
std::cout << "enter student " << i + 1 << " name\n";
if (!(std::cin >> s.name)) /* validate all input, ctrl + z to end input */
break;
(注意:变量i
只需要提示输入时显示学号,所有容器都提供.size()
成员函数告诉你里面有多少对象。)
完成输入后,您可以使用 Range-based for loop 遍历集合中的每个学生,输出所需的信息。例如:
std::cout << "\nwith out sorting \n";
for (auto& s : students) { /* output in order of cgpa w/o sorting */
std::cout << " NAME\tAGE\tCGPA\n"
<< s.name << "\t" << s.age << "\t" << s.cgpa << '\n';
}
总而言之,你可以这样做:
#include <iostream>
#include <string>
#include <set>
struct student { /* struct student */
std::string name;
int age;
float cgpa;
};
/* overload of < comparing student by cgpa */
bool operator <(const student& a, const student& b) {
return a.cgpa < b.cgpa;
}
int main(void)
{
/* create std::set of students using std::less for compare */
std::set<student, std::less<const student&>> students {};
for (int i = 0; ; i++) {
student s {}; /* temporary struct to add to set */
std::cout << "enter student " << i + 1 << " name\n";
if (!(std::cin >> s.name)) /* validate all input, ctrl + z to end input */
break;
std::cout << "enter student " << i + 1 << " age\n";
if (!(std::cin >> s.age))
break;
std::cout << "enter student " << i + 1 << " cgpa\n";
if (!(std::cin >> s.cgpa))
break;
students.insert(s); /* insert student in set */
}
std::cout << "\nwith out sorting \n";
for (auto& s : students) { /* output in order of cgpa w/o sorting */
std::cout << " NAME\tAGE\tCGPA\n"
<< s.name << "\t" << s.age << "\t" << s.cgpa << '\n';
}
}
(注意: 看看Why is “using namespace std;” considered bad practice?。早点养成好习惯比以后改掉坏习惯要容易得多...)
(注 2: 您可以考虑使用 getline(std::cin, s.name)
来输入学生姓名,这样您就可以处理带空格的姓名,例如 Firstname Lastname
,例如 Mickey Mouse
,由您决定)
重新添加 system("pause");
以保持您的终端 window 根据需要打开。
例子Use/Output
现在只需输入任意数量的学生的学生数据,然后通过生成手动 EOF
如上所述终止输入,例如
$ ./bin/set_student_grades
enter student 1 name
gates
enter student 1 age
20
enter student 1 cgpa
2.12
enter student 2 name
della
enter student 2 age
21
enter student 2 cgpa
2.00
enter student 3 name
jim
enter student 3 age
30
enter student 3 cgpa
3.12
enter student 4 name
with out sorting
NAME AGE CGPA
della 21 2
NAME AGE CGPA
gates 20 2.12
NAME AGE CGPA
jim 30 3.12
这提供了一种按 cgpa
顺序存储和提供学生数据的方法,无需显式 sort
。当然 std::set
会为您做到这一点,但如果避免显式排序是您程序的意图,那么这是一个很好的选择。如果您还有其他问题,请告诉我。
#include<iostream>
#include<string>
using namespace std;
struct student {
string name;
int age;
float cgpa;
};
void main() {
student *ptr;
int size;
cout << "enter size \n"; cin >> size;
ptr = new student[size];
for (int i = 0; i < size; i++)
{
cout << "enter student " << i + 1 << " name\n";
cin >> ptr[i].name;
cout << "enter student " << i + 1 << " age\n";
cin >> ptr[i].age;
cout << "enter student " << i + 1 << " cgpa\n";
cin >> ptr[i].cgpa;
}
string temp1; int temp2; float temp3;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (ptr[i].cgpa < ptr[j].cgpa)
{
temp1 = ptr[j].name;
ptr[j].name = ptr[i].name;
ptr[i].name = temp1;
temp2 = ptr[j].age;
ptr[j].age = ptr[i].age;
ptr[i].age = temp2;
temp3 = ptr[j].cgpa;
ptr[j].cgpa = ptr[i].cgpa;
ptr[i].cgpa = temp3;
}
}
}
for (int i = 0; i < size; i++) {
cout << " NAME\tAGE\tCGPA\n";
cout << ptr[i].name << "\t" << ptr[i].age << "\t" << ptr[i].cgpa << endl;
}
delete[] ptr;
system("pause");
}