列表的一个元素已排序,其他元素未排序

one element of list is sorted others aren't

本文关键字:排序 元素 其他 一个 列表      更新时间:2023-10-16

好的,我正在编写一个程序,我必须在其中输入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].gradesort_grade()中,s[i].namesort_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

冒泡排序的一般问题

  1. 您使用标准进行排序,但只交换标准而不交换其他特征!temp应该是struct student
  2. 索引移动1。在这两种排序情况下,您从1n-1开始,但索引ii+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