列表的一个元素已排序,其他元素未排序
one element of list is sorted others aren't
好的,我正在编写一个程序,我必须在其中输入n个学生的姓名,名字和成绩。完成之后,我必须按字母顺序排列它们,如果名字匹配,就排在名字后面。然后我有另一个选择排序后的成绩。这是我到目前为止的代码:
#include<iostream>
#include<string.h>
#include<conio.h>
#include<stdio.h>
using namespace std;
struct student
{
char name[30];
char firstname [50];
int grade;
}s[50];
int i,n,o,done=0;
void add_student()
{
cout<<"Number of students:"<<" ";
cin>>n;
cout<<endl;
for(i=1; i<=n; i++)
{
fflush(stdin);
cout<<"Student"<<" "<<i<<":"<<endl;
cout<<"name of student:"<<" ";
gets(s[i].name);
cout<<"first name of student:"<<" ";
gets(s[i].firstname);
cout<<"grade of student:"<<" ";
cin>>s[i].grade;
cout<<endl;
}
}
void sort_name()
{
char temp[30];
while(!done)
{
done=1;
for(i=1; i<n; i++)
{
if(strcmp(s[i].name,s[i+1].name)>0)
{
strcpy(temp,s[i].name);
strcpy(s[i].name,s[i+1].name);
strcpy(s[i+1].name,temp);
}
}
}
for(i=1; i<=n; i++)
{
cout<<"Student"<<" "<<i<<":"<<endl;
cout<<"Name"<<":"<<s[i].name<<endl;
cout<<"Firstname"<<":"<<s[i].firstname<<endl;
cout<<endl;
}
}
void sort_grade()
{
int temp;
while(!done)
{
done=1;
for(i=1;i<n;i++)
{
if(s[i].grade>s[i+1].grade)
{
temp=s[i].grade;
s[i].grade=s[i+1].grade;
s[i+1].grade=temp;
done=0;
}
}
}
for(i=1; i<=n; i++)
{
cout<<"Student"<<" "<<i<<":"<<endl;
cout<<"Name"<<":"<<s[i].name<<endl;
cout<<"Firstname"<<":"<<s[i].firstname<<endl;
cout<<"Grade"<<":"<<s[i].grade<<endl;
cout<<endl;
}
}
void list_students()
{
int i;
for(i=1; i<=n; i++)
{
cout<<"Student"<<" "<<i<<":"<<endl;
cout<<"Name"<<":"<<s[i].name<<endl;
cout<<"Firstname"<<":"<<s[i].firstname<<endl;
cout<<"Grade"<<":"<<s[i].grade<<endl;
cout<<endl;
}
}
int main()
{
do
{
cout<<"Menu:"<<endl;
cout<<"1.Add students"<<endl;
cout<<"2.Sort by name"<<endl;
cout<<"3.Sort by grade"<<endl;
cout<<"4.List students"<<endl;
cout<<"5.Exit"<<endl<<endl;
cout<<"Pick option : ";
cin>>o;
cout<<endl;
switch (o)
{
case 1:add_student();
break;
case 2:sort_name();
break;
case 3:sort_grade();
break;
case 4:list_students();
break;
}
}while (o!=5);
}
问题是,每当我按年级排序时,例如,学生A的成绩是9,学生B的成绩是7,排序后它会告诉我学生A的成绩是7,学生B的成绩是9。我知道我告诉排序函数只排序等级,而不是虽然名称,但我不知道如何修复它。这可能是一些非常简单的东西,我想它涉及到某种指针,但我真的不知道。如果你能告诉我如何在firstname之后排序如果名字是相同的位。如果有人能帮助我,我会非常感激。提前谢谢你!S如果有人能给我任何指针关于这个问题在c中是什么样子的,我将非常非常感激)
不要只交换结构的一部分(s[i].grade
在sort_grade()
中,s[i].name
在sort_name()
中),你应该交换整个结构。它应该像下面这样:
void swap(int n, int m)
{
char temp_string[50];
int temp_int;
strcpy(temp,s[n].name);
strcpy(s[n].name,s[m].name);
strcpy(s[m].name,temp);
strcpy(temp,s[n].firstname );
strcpy(s[n].firstname ,s[m].firstname );
strcpy(s[m].firstname ,temp);
temp_int = s[n].grade;
s[n].grade = s[m].grade;
s[n].grade = temp_int;
}
void sort_name()
{
char temp[30];
while(!done)
{
done=1;
for(i=1; i<n; i++)
{
if(strcmp(s[i].name,s[i+1].name)>0)
{
swap(i, i+1);
}
}
}
}
代码中有很多错误。
在这里,我为你修复了它们,但它可能受到我的编码风格的影响:
标题:
#include <iostream>
#include <cstring> //not <string.h>
#include <cstdio> //not <stdio.h>
//#include <conio.h> //you don't use any functionality from this header
#include <limits>
#include <cinttypes>
名称空间:
// dont use "using namespace std;", it's considered bad (here it might not be visible)
Struct就像ok?我认为:
struct student
{
char name[30];
char firstname [50];
int grade;
}s[50];
不要依赖全局变量(这个程序模型需要n
):
int /*i,*/n=0/*,o,done=0*/; //don't declare global variables if you don't need them to be global
修复add_student()
(许多错误):
void add_student()
{
std::cout<<"Number of students:"<<" ";
std::cin>>n;
std::cout<<std::endl;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n'); //this is how you flush in c++
for(int i=0/*1*/; i</*=*/n; i++) //declare iterator in loop
{ //also, first element index is 0, not 1!
//fflush(stdin); //NEVER do that in C++, std::std::endl flushes output anyways
std::cout<<"Student"<<" "<<i+1<<":"<<std::endl/*;*/ //dont spam std::cout too much
/*std::cout*/<<"name of student:"<<" "; //just go to next line and start with "<<"
std::gets(s[i].name);
std::cout<<"first name of student:"<<" ";
std::gets(s[i].firstname);
std::cout<<"grade of student:"<<" ";
std::cin>>s[i].grade;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
std::cout<<std::endl; //this std::std::endl call flushes output, so that "C flushin" didn't do anything
}
}
排序函数(很多错误):
void sort_name()
{
bool done = false; //prefer bool over int for logical expressions
/*char temp[30];*/ //not gonna use this, you need whole student, not only name
student temp;
while(!done)
{
// this whole section is wrong, you just go around swapping
// students names, not students themselfs
// done=1;
// for(i=0/*1*/; i<n-1; i++)
// {
// if(strcmp(s[i].name,s[i+1].name)>0)
// {
// strcpy(temp,s[i].name);
// strcpy(s[i].name,s[i+1].name);
// strcpy(s[i+1].name,temp);
// }
// }
done = true;
for(int i=0; i<n-1; ++i)
{
if(strcmp(s[i].name, s[i+1].name)>0)
{
std::cout << "swapping" << std::endl;
temp = s[i];
s[i] = s[i+1];
s[i+1] = temp;
done = false;
}
}
}
for(int i=0/*1*/; i</*=*/n; i++)
{
std::cout<<"Student"<<" "<<i+1<<":"<<std::endl
<<"Name"<<":"<<s[i].name<<std::endl
<<"Firstname"<<":"<<s[i].firstname<<std::endl
<<std::endl;
}
}
void sort_grade()
{
bool done = false;
student temp;
//exact same mistakes like in sort_name()
while(!done)
{
done = true;
for(int i=0; i<n-1; ++i)
{
if(s[i].grade > s[i+1].grade)
{
temp = s[i];
s[i] = s[i+1];
s[i+1] = temp;
done = false;
}
}
}
for(int i=0/*1*/; i</*=*/n; i++)
{
std::cout<<"Student"<<" "<<i+1<<":"<<std::endl
<<"Name"<<":"<<s[i].name<<std::endl
<<"Firstname"<<":"<<s[i].firstname<<std::endl
<<"Grade"<<":"<<s[i].grade<<std::endl
<<std::endl;
}
}
list_students()
函数(cout
垃圾邮件和索引再次移位):
void list_students()
{
for(int i=0/*1*/; i</*=*/n; i++)
{
std::cout<<"Student"<<" "<<i+1<<":"<<std::endl
<<"Name"<<":"<<s[i].name<<std::endl
<<"Firstname"<<":"<<s[i].firstname<<std::endl
<<"Grade"<<":"<<s[i].grade<<std::endl
<<std::endl;
}
}
和main()
(使int o
成为一个局部变量,并固定cout
为垃圾):
int main()
{
int o;
do
{
//please, don't spam std::cout like that, it hurts
std::cout<<"Menu:"<<std::endl
<<"1.Add students"<<std::endl
<<"2.Sort by name"<<std::endl
<<"3.Sort by grade"<<std::endl
<<"4.List students"<<std::endl
<<"5.Exit"<<std::endl<<std::endl
<<"Pick option : ";
std::cin>>o;
std::cout<<std::endl;
switch (o)
{
case 1:add_student();
break;
case 2:sort_name();
break;
case 3:sort_grade();
break;
case 4:list_students();
break;
}
}while (o!=5);
}
总之,任重道远!但是学习你的代码,读一些好书,这样你可以提高。
编辑:标题:
cstdio .h namespace
名称空间:
为什么使用命名空间std"被认为是不好的做法?
全局变量:
全局变量不好吗?
C/c++中的索引:
为什么在'C'中索引从0开始?
在c++和cin/get中刷新输入/输出~问题解决方案:
(输出)
c++:"std:: endl"与" n"
(输入)
输入
Anti-cout垃圾邮件:http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt
交换结构:
c++ sort with structs
冒泡排序的一般问题
- 您使用标准进行排序,但只交换标准而不交换其他特征!
temp
应该是struct student
- 索引移动1。在这两种排序情况下,您从
1
到n-1
开始,但索引i
和i+1
:缺少第一个元素和溢出数组。
还有名字"冒泡排序"是错误的(漏掉了矫揉造作):
I'd do this
while(!done)
{
done = 1;
for(i=0; i < n-1; i++)
{
if(strcmp(s[i].name, s[i+1].name) > 0)
{
done = 0; // still work to do
temp = s[i];
s[i] = s[i+1];
s[i+1] = temp;
}
}
}
排序等级也错误:修复版本:
void sort_grade()
{
struct student temp;
while(!done)
{
done = 1;
for(i=0; i < n-1; i++) // loop boundaries were not OK
{
if(s[i].grade > s[i+1].grade)
{
temp = s[i];
s[i] = s[i+1];
s[i+1] = temp;
done = 0;
}
}
}
}
更不用说c++有使用标准的高效排序函数,比这个要好得多(除非你必须这样做)
在交换时使用memcpy()类函数并交换整个结构而不是name/gRade
- 查找两个排序向量中共有的元素
- C++ 如何比较n个排序的整数向量以找到互元素?
- 如何在 c++ 中根据第二个元素按降序对列表进行排序
- 对的排序向量 (std::vector<pair<int, int>>) 按对的第一个元素搜索并更新第二个元素值
- 高级选择排序 - 在一次迭代中搜索两个元素
- 为什么用户定义的函数不按照给定的顺序对相同长度的元素进行排序?
- 为什么这个选择排序算法仍然切换一个元素,当它已经是其他元素中最小的元素时?
- 快速排序 - 三个中位数枢轴选择 - 某些元素顺序不正确
- 将一系列已排序的元素划分为相邻组
- 如何通过保持第一个插入的位置来对列表中插入的其余元素进行排序?
- 保持排序的数据结构,允许log N插入时间,并且可以返回我在log N中查找的元素的索引
- "x"的所有元素都存在于"y"(排序向量)中吗?
- 如何根据对的第二个元素对 STL c++ 中的一组对进行排序?
- 如何在保持它们连接到同一元素的同时对 2 个数组进行排序?
- C++:结构与用于排序元素的函数
- 无法在阵列中重新排序元素-rapidjson
- 比较两个向量中的未排序元素
- 我如何在队列中排序元素
- c++中的Hashmap不排序元素
- c++插入排序元素