使用成员作为数组对结构数组进行排序

时间:2016-11-08 13:13:37

标签: c

问题: - 编写交流程序,接受4个科目中10名学生的姓名和标记,并按4个科目中标记平均值的升序打印等级列表。为每个学生打印个人标记。如果每个科目的通过标记是35,打印所有4个科目中失败的学生的姓名。

采用的算法是: -

1.Start
2.Get student name and marks in 4 subjects
3.Calculate average for each student
4.Sort average in acsending order
5.Swap student names in the same order as average
6.Swap student marks in the same order as average
7.Display rank list
8.Display individual marks for each student
9.Stop

我的问题: - 我编写了以下程序只是为了偶然发现算法的第6步。有没有办法完成第6步?

#include<stdio.h>
#include<conio.h>
#include<string.h>
#define sub 3
#define sno 3
struct student
{
  char sname[20];
  int avg,marks[4];
};
void main()
{
  int i,j,max,bit=0;
  char swapname[20];
  struct student s[sno];
  clrscr();
  for(i=0;i<sno;i++)
  {
   printf("Enter the name of student %d:",i+1);
   scanf("%s",s[i].sname);
   printf("Enter marks in four subjects\t");
   for(j=0;j<sub;j++)
   {
    scanf("%d",&s[i].marks[j]);
   }
   //initialize structure member
   s[i].avg=0;
   //compute average
   for(j=0;j<sub;j++)
   {
    s[i].avg+=s[i].marks[j];
   }
   s[i].avg/=sub;
  }//FOR LOOP ends
  printf("\n\n");
  //Displaying failed students
  printf("List of the failed students:\n");
  for(i=0;i<sno;i++)
  {
   if(s[i].marks[0]<35&&s[i].marks[1]<35&&s[i].marks[2]<35&&s[i].marks[3]<35)
   {
    printf("%s\n\n",s[i].sname);
    if(bit==0)
     bit=1;
   }
  }
  if(bit==0)
   printf("No one fails!\n\n");
  //SORTING
  for(i=0;i<sno;i++)
  {
   for(j=i+1;j<sno;j++)
   {
    if(s[i].avg>s[j].avg)
    {
     max=s[i].avg;
     s[i].avg=s[j].avg;
     s[j].avg=max;
     strcpy(swapname,s[i].sname);
     strcpy(s[i].sname,s[j].sname);
     strcpy(s[j].sname,swapname);

    }
   }
  }
  //Display result
  printf("Student Name in the ascending order of Average obtained:\n");
  for(i=0;i<sno;i++)
  {
    printf("%s:\t",s[i].sname);
    printf("%d\n",s[i].avg);
  }

  getch();
}

4 个答案:

答案 0 :(得分:2)

您可以通过交换整个struct一次性完成第5步和第6步。

if(s[i].avg > s[j].avg)
{
    struct student temp = s[i];
    s[i] = s[j];
    s[j] = temp;
}

答案 1 :(得分:1)

只需 在循环中使用额外的临时变量 来交换两名学生的所有分数,就像您使用swapname来交换名称一样

 strcpy(swapname,s[i].sname);//Swap student names
 strcpy(s[i].sname,s[j].sname);
 strcpy(s[j].sname,swapname);

 for(int index = 0; index < 4; index++) //swapping student marks
 {
     int temp = s[i].marks[index];
     s[i].marks[index] = s[j].marks[index];
     s[j].marks[index] = temp;
 }

提示:下次遇到这样的问题(交换数组的所有值)时尝试使用循环

答案 2 :(得分:1)

首先,您应该将int avg更改为fload avg。然后在交换名称后,您可以使用另一个for loop进行标记的交换。它更容易,因为您不需要使用任何函数,您只需使用临时变量:

int tmpMark, k;
for (k=0; k<sub; k++){
   tmpMark=s[i].marks[k];
   s[i].marks[k] = s[j].marks[k];
   s[j].marks[k] = temp;
}

答案 3 :(得分:1)

我认为改变排序方式会更好。由于您将所有内容存储在struct元素中,因此您可以交换整个元素而不是单个字段。

我不知道您提供的算法是否是作业约束,或者您是否想出了它。我在考虑后者。要交换结构的两个元素,我使用了一个临时变量和memcpy函数。这是注释代码:

...

struct student s[sno], tmp;

...

/* Sorting:
 *
 * Since everything is stored in the @s struct, you can swap
 * the elements of the struct itself, that simplifies the code.
 */
for (i = 0; i < sno; i++) {
    for (j = i + 1; j < sno; j++) {
        if (s[i].avg > s[j].avg) {
            /* backup copy */
            memcpy(&tmp, &s[i], sizeof tmp);

            /* swap elements */
            memcpy(&s[i], &s[j], sizeof tmp);

            /* restore the copy */
            memcpy(&s[j], &tmp, sizeof tmp);
        }
    }
}