用c语言编写软件完成以下任务:一批选手参加比赛,比赛的规则是最后得分越高,名次越低。当半决赛结束时,要在现场按照选手的出场顺序宣布最后得分和最后名次,获得相同分数的选手具有相同的名次,名次连续编号,不用考虑同名次的选手人数。例如:
选手序号: 1,2,3,4,5,6,7
选手得分: 5,3,4,7,3,5,6
输出名次为:3,1,2,5,1,3,4
首先题目要求按照选手的出场顺序(即选手的序号)宣布最后得分,也就是说并不是按照名次的前后顺序输出选手信息,而是按照选手的序号输出最后的得分和名次。
其次,题目要求获得相同分数的选手具有相同的名次,并且名次连续编号,不用考虑同名次的选手人数,因此不存在并列名次占位的情况,也就是说如果存在并列第一,那么下一名的名次是第二名,而不是第三名。
另外,如果只是简单地对选手的得分序列进行排序,那么选手的 得分与选手的序号就不能构成一一对应的关系,那么这样的排序也就没有意义了。出于这几点考虑,此问题并非只使用简单的排序运算就可以解决的。
使用结构体来解决该问题。将每个选手的信息(包括序号、得分、名次)存放在一个结构体变量中,然后组成一个结构体数组。
最开始每个结构体变量中只存放选手的序号和得分的信息,然后以选手的得分为比较对象,从小到大进行排序。算法描述如下:
void sortScore(struct player psn[], int n)
{
int i, j;
struct player tmp;
for(i=0; i<n-1; i++)
for(j=0; j<n-1-i; j++)
{
if(psn[j].score>psn[j+1].score)
{
tmp = psn[j];
psn[j] = psn[j+1];
psn[j+1] = tmp;
}
}
}
上面算法中使用了冒泡排序法,对含有n个元素的结构体数组psn中的元素按照score从小到大的顺序进行排序。排序后的数组psn按照score的值从小到大排列。
接着指定每一位选手的名次。因为此时结构体数组psn已按照score从小到大排列了,因此就比较容易设定每一位选手的名次了。使用算法描述如下:
void setRand(struct player psn[], int n)
{
int i,j=2;
psn[0].rand=1;
for(i=1; i<n; i++)
{
if(psn[i].score!=psn[i-1].score )
{
psn[i].rand=j;
j++;
}
else
psn[i].rand=psn[i-1].rand;
}
}
首先给第一位选手psn[0]的名次设定为1,因为它的得分是最少的。然后依次给psn[2]〜psn[n-1]设定名次。如果psn[i].score不等于psn[i-1].score,说明psn[i]的名次要落后一名;否则psn[i]的名次与psn[i-1]的名次相同。
最后再按照选手的序号重新排序,以便能够按照选手的序号输出结果。该算法描述如下:
void sortNum(struct player psn[], int n)
{
int i,j;
struct player tmp;
for(i=0; i<n-1; i++)
for(j=0; j<n-1-i; j++)
{
if(psn[j].num>psn[j+1].num)
{
tmp = psn[j];
psn[j] = psn[j+1];
psn[j+1] = tmp;
}
}
}
下面是完整的代码:
#include <stdio.h>
struct player{
int num;
int score;
int rand;
};
void sortScore(struct player psn[], int n)
{
int i, j;
struct player tmp;
for(i=0; i<n-1; i++)
for(j=0; j<n-1-i; j++)
{
if(psn[j].score>psn[j+1].score)
{
tmp = psn[j];
psn[j] = psn[j+1];
psn[j+1] = tmp;
}
}
}
void setRand(struct player psn[], int n)
{
int i,j=2;
psn[0].rand=1;
for(i=1; i<n; i++)
{
if(psn[i].score!=psn[i-1].score )
{
psn[i].rand=j;
j++;
}
else
psn[i].rand=psn[i-1].rand;
}
}
void sortNum(struct player psn[], int n)
{
int i,j;
struct player tmp;
for(i=0; i<n-1; i++)
for(j=0; j<n-1-i; j++)
{
if(psn[j].num>psn[j+1].num)
{
tmp = psn[j];
psn[j] = psn[j+1];
psn[j+1] = tmp;
}
}
}
void sortRand(struct player psn[], int n)
{
sortScore(psn,n); /*以分数为关键字排序*/
setRand(psn,n); /*按照分数排名次*/
sortNum(psn,n); /*按照序号重新排序*/
}
int main()
{
struct player psn[7]={{1, 5, 0}, {2, 3, 0}, {3, 4, 0}, {4, 7, 0}, {5, 3, 0}, {6, 5, 0}, {7, 6, 0}};
int i;
sortRand(psn, 7);
printf("num score rand \n");
for(i=0; i<7; i++)
{
printf("%d%6d%6d\n", psn[i].num, psn[i].score, psn[i].rand);
}
getche();
return 0;
}
运行结果: