【c/c++编程-排序问题】成绩排序、整数奇偶排序、国名排序、日志排序、字符串排序

目录

成绩排序

整数奇偶排序1.0

成绩排序2.0

国名排序

日志排序

整数奇偶排序2.0

字符串排序

解一 

解二 

字符串排序3

后缀子串排序

EXCEL排序

特殊排序

成绩排序3.0

大整数排序


成绩排序

题目描述:

输入任意(用户,成绩)序列,可以获得成绩从高到低或从低到高的排列,相同成绩都按先录 入排列在前的规则处理。

输入描述:

输入多行,先输入要排序的人的个数,然后输入排序方法 0(降序)或者 1(升序)再分别输 入他们的名字和成绩,以一个空格隔开 输出描述: 按照指定方式输出名字和成绩,名字和成绩之间以一个空格隔开

输入样例#:

3

0

fang 90

yang 50

ning 70

输出样例#:

fang 90

ning 70

yang 50

  • 稳定排序,sort 排序是不稳定的,排序之后相对次序有 可能发生改变。解决这个问题有两个方法,一个是用 stable_sort 函数,它的用法和 sort 一 样,但是它是稳定的,所以如果我们遇到有稳定的需求的排序时,可以用它。另一个方法是给 每一个输入增加一个递增的下标,然后二级排序,当值相同时,下标小的排在前面 
#include <bits/stdc++.h>
using namespace std;

struct Student{
	string name;
	int grade;
}stu[1000];

bool cmp1(Student a,Student b){
	return a.grade>b.grade;
}//从大到小排序

bool cmp2(Student a,Student b){
	return a.grade<b.grade;
}//从小到大排序

int main(){
	int n,order;
	while(cin>>n){
        cin>>order;
		for(int i = 0;i<n;i++){
			cin>>stu[i].name>>stu[i].grade;
		}
		if(order = 0)
			stable_sort(stu,stu+n,cmp1);
		else
			stable_sort(stu,stu+n,cmp2);
		for(int i = 0;i<n;i++){
			cout<<stu[i].name<<" "<<stu[i].grade<<endl;
		}
		
	} 

	return 0;
}

整数奇偶排序1.0

题目描述:

输入 n 个数进行排序,要求先按奇偶后按从小到大的顺序排序。

输入描述:

第一行输入一个整数 n,表示总共有多少个数,n<=1000。 第二行输入 n 个整数,用空格隔开。

输出描述:

输出排序之后的结果。

输入样例#:

8 1 2 3 4 5 6 7 8

输出样例#:

1 3 5 7 2 4 6 

#include <bits/stdc++.h>
using namespace std;

bool cmp(int a,int b){
	if(a%2==b%2) //同奇同偶,按照从小到大排序
	return a<b;
	else
	return (a%2) >(b%2);//奇数在偶数前面
}

int main(){
	int n;
	int a[1005] = {0};
	while(cin>>n){
		for(int i = 0;i<n;i++)
			cin>>a[i];
	sort(a,a+n,cmp);
		for(int i = 0;i<n;i++)
		cout<<a[i]<<" "<<endl;

	} 

	return 0;
}

成绩排序2.0

题目描述

用一维数组存储学号和成绩,然后,按成绩排序输出。

输入描述:

输入第一行包括一个整数N(1<=N<=100),代表学生的个数。
接下来的N行每行包括两个整数p和q,分别代表每个学生的学号和成绩。

输出描述:

按照学生的成绩从小到大进行排序,并将排序后的学生信息打印出来。
如果学生的成绩相同,则按照学号的大小进行从小到大排序。
#include <bits/stdc++.h>
using namespace std;

struct Student{
	int id;
	int grade;
}stu[1005];

bool cmp(Student a,Student b){
	if (a.grade != b.grade)
		return a.grade <b.grade;
	else 
		return a.id < b.id;//从小到大 
}

int main(){
	int n;
	while(cin>>n){
		for(int i = 0;i<n;i++)
			cin>>stu[i].id>>stu[i].grade;
			
		sort(stu,stu+n,cmp);
		
		for(int i = 0;i<n;i++)
			cout<<stu[i].id<<" "<<stu[i].grade<<endl;
	} 
	return 0;
}

国名排序

题目描述

问题描述: 小李在准备明天的广交会,明天有来自世界各国的客房跟他们谈生意,小李要尽快的整理出名单给经理,你能帮他把客户来自的国家按英文字典次序排好吗?   例如小李手上有来自加拿大,美国,中国的名单,排好的名单应是美国,加拿大,中国

输入描述:

第一行为一个n(n<=100)表示n个国家,第2行到第n+1行分别为n个国家的名字.

输出描述:

输出n个国家按字典顺序的排列.

输入样例#:

3
China
Canada
America

输出样例

America
Canada
China
#include <bits/stdc++.h>
using namespace std;


int main(){
	int n;
	
	while(cin>>n){
		string s[n];
		for(int i = 0;i<n;i++)
			cin>>s[i];
			
		sort(s,s+n);
		
		for(int i = 0;i<n;i++)
			cout<<s[i]<<endl;
	} 
	return 0;
}

日志排序

题目描述

有一个网络日志,记录了网络中计算任务的执行情况,每个计算任务对应一条如下形式的日志记录: “hs_10000_p”是计算任务的名称, “2007-01-17 19:22:53,315”是计算任务开始执行的时间“年-月-日 时:分:秒,毫秒”, “253.035(s)”是计算任务消耗的时间(以秒计) hs_10000_p 2007-01-17 19:22:53,315 253.035(s) 请你写一个程序,对日志中记录计算任务进行排序。 时间消耗少的计算任务排在前面,时间消耗多的计算任务排在后面。 如果两个计算任务消耗的时间相同,则将开始执行时间早的计算任务排在前面。

输入描述:

日志中每个记录是一个字符串,每个字符串占一行。最后一行为空行,表示日志结束。日志中最多可能有10000条记录。
计算任务名称的长度不超过10,开始执行时间的格式是YYYY-MM-DD HH:MM:SS,MMM,消耗时间小数点后有三位数字。
计算任务名称与任务开始时间、消耗时间之间以一个或多个空格隔开,行首和行尾可能有多余的空格。

输出描述:

排序好的日志记录。每个记录的字符串各占一行。
输入的格式与输入保持一致,输入包括几个空格,你的输出中也应该包含同样多的空格。

输入样例#:

hs_10000_p   2007-01-17 19:22:53,315     253.035(s)
hs_10001_p   2007-01-17 19:22:53,315     253.846(s)
hs_10002_m   2007-01-17 19:22:53,315     129.574(s)
hs_10002_p   2007-01-17 19:22:53,315     262.531(s)
hs_10003_m   2007-01-17 19:22:53,318     126.622(s)
hs_10003_p   2007-01-17 19:22:53,318     136.962(s)
hs_10005_m   2007-01-17 19:22:53,318     130.487(s)
hs_10005_p   2007-01-17 19:22:53,318     253.035(s)
hs_10006_m   2007-01-17 19:22:53,318     248.548(s)
hs_10006_p   2007-01-17 19:25:23,367    3146.827(s)

输出样例#:

hs_10003_m   2007-01-17 19:22:53,318     126.622(s)
hs_10002_m   2007-01-17 19:22:53,315     129.574(s)
hs_10005_m   2007-01-17 19:22:53,318     130.487(s)
hs_10003_p   2007-01-17 19:22:53,318     136.962(s)
hs_10006_m   2007-01-17 19:22:53,318     248.548(s)
hs_10000_p   2007-01-17 19:22:53,315     253.035(s)
hs_10005_p   2007-01-17 19:22:53,318     253.035(s)
hs_10001_p   2007-01-17 19:22:53,315     253.846(s)
hs_10002_p   2007-01-17 19:22:53,315     262.531(s)
hs_10006_p   2007-01-17 19:25:23
#include <bits/stdc++.h>
using namespace std;

struct Task{
	char allLog[200];
	char name[12];
	char start_day[15];
	char start_time[15];
	char wastetime[15];
}tasks[1005];

bool cmp(Task a,Task b){
	int len1 = strlen( a.wastetime);
	int len2 = strlen( b.wastetime);
	if (len1!=len2) 	{return len1 < len1;
	}
	else {
		int x = strcmp(a.wastetime,b.wastetime);
		if (x!=0){
		return x<0;
		} 
		else{
		int x = strcmp( a.start_day,b.start_day);
		if (x!=0) {
		return x<0;}
		else{
		return strcmp( a.start_time,b.start_time)<0;
		} 
   }
 }
}

int main(){
	int n = 0;

		while(gets(tasks[n].allLog))
		{		
			sscanf(tasks[n].allLog,"%s%s%s%s",tasks[n].name,tasks[n].start_day,tasks[n].start_time,tasks[n].wastetime);
			n++;
		}

		sort(tasks,tasks+n,cmp);
		
		for(int i = 0;i<n;i++){
			cout<<tasks[i].allLog<<endl;
		}
	return 0;
}

整数奇偶排序2.0

题目描述

输入10个整数,彼此以空格分隔。重新排序以后输出(也按空格分隔),要求: 1.先输出其中的奇数,并按从大到小排列; 2.然后输出其中的偶数,并按从小到大排列。

输入描述:

任意排序的10个整数(0~100),彼此以空格分隔。

输出描述:

可能有多组测试数据,对于每组数据,按照要求排序后输出,由空格分隔。

1. 测试数据可能有很多组,请使用while(cin>>a[0]>>a[1]>>...>>a[9])类似的做法来实现;
2. 输入数据随机,有可能相等。

输入样例#:

4 7 3 13 11 12 0 47 34 98

输出样例#:

47 13 11 7 3 0 4 12 34 98
#include <bits/stdc++.h>
using namespace std;

bool cmp(int a,int b){
	//两个数都是奇数 
	if(a%2 &&b%2) {
	return a>b;
	}
	//两个都为偶数 
	else if(a%2==0 &&b%2==0) {
	return a<b;
	}
	else return (a%2) > (b%2) ;
}

int main(){
	int a[10] ;
	while(cin>>a[0]>>a[1]>>a[2]>>a[3]>>a[4]>>a[5]>>a[6]>>a[7]>>a[8]>>a[9]){
	    sort(a,a+10,cmp);
		for (int i = 0;i<10;i++){	
		cout<<a[i]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

字符串排序

题目描述

 输入一个长度不超过20的字符串,对所输入的字符串,按照ASCII码的大小从小到大进行排序,请输出排序后的结果

输入描述:

一个字符串,其长度n<=20

输出描述:

输入样例可能有多组,对于每组测试样例,
按照ASCII码的大小对输入的字符串从小到大进行排序,输出排序后的结果

输入样例#:

dcba

输出样例#:

abcd

解一 

#include <bits/stdc++.h>
using namespace std;

int main(){
	string s;
	cin>>s;
	sort(s.begin(),s.end());
	cout<<s<<endl;
	return 0;
}

解二 

#include <bits/stdc++.h>
using namespace std;

int main(){
	char s[20];
	scanf("%s",&s);
	int len = strlen(s);
	sort(s,s+len);
	printf("%s",s);
	return 0;
}

字符串排序3

题目描述

先输入你要输入的字符串的个数。然后换行输入该组字符串。每个字符串以回车结束,每个字符串少于一百个字符。 如果在输入过程中输入的一个字符串为“stop”,也结束输入。 然后将这输入的该组字符串按每个字符串的长度,由小到大排序,按排序结果输出字符串。

输入描述:

字符串的个数,以及该组字符串。每个字符串以‘\n’结束。如果输入字符串为“stop”,也结束输入.

输出描述:

可能有多组测试数据,对于每组数据,
将输入的所有字符串按长度由小到大排序输出(如果有“stop”,不输出“stop”)。

根据输入的字符串个数来动态分配存储空间(采用new()函数)。每个字符串会少于100个字符。
测试数据有多组,注意使用while()循环输入。

输入样例#:

5
sky is grey
cold
very cold
stop
3
it is good enough to be proud of
good
it is quite good

输出样例#:

cold
very cold
sky is grey
good
it is quite good
it is good enough to be proud of
#include <bits/stdc++.h>
using namespace std;
typedef long long ll; 

bool cmp(string a,string b){
	return  a.length() <b.length() ;
}

int main(){
	int n;
	while(cin>>n)
	{	
		getchar();//接收cin完的空格
		string a[n];
		for(int i;i<n;i++)
		{
			string s;
			getline(cin,s);
			if(s==" ")
			{
				i--;//遇到空格退回空格前面的字符
				continue;
			}
			if(s == "stop")
			{
				n = i;//停止输入,i比n小1
				break;
			}
			else   a[i] = s;
		}
		sort(a,a+n,cmp);
		for(int i = 0;i<n;i++)
			cout<<a[i]<<endl;
	}
	return 0;
}

后缀子串排序

题目描述

对于一个字符串,将其后缀子串进行排序,例如grain 其子串有: grain rain ain in n 然后对各子串按字典顺序排序,即: ain,grain,in,n,rain

输入描述:

多组数据输入。
每个案例为一行字符串。

输出描述:

将子串排序输出

输入样例#:

grain

输出样例#:

ain
grain
in
n
rain
#include <bits/stdc++.h>
using namespace std;
typedef long long ll; 

bool cmp(string a,string b){
	return  a < b;
}
int main(){
	string s;
	string s2[1005];
	
	while(cin>>s){
		int len = s.size();
		for (int i = 0;i<len;i++){
			string a = s.substr(i,len-i);
			s2[i] = a;
		}
		sort(s2,s2+len,cmp);
		for(int i = 0;i<len;i++)
		cout<<s2[i]<<endl;
	}
	return 0;
}

EXCEL排序

题目描述

Excel可以对一组纪录按任意指定列排序。现请你编写程序实现类似功能。     对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3 时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

输入描述:

测试输入包含若干测试用例。每个测试用例的第1行包含两个整数 N (N<=100000) 和 C,其中 N 是纪录的条数,C 是指定排序的列号。以下有N行,每行包含一条学生纪录。每条学生纪录由学号(6位数字,同组测试中没有重复的学号)、姓名(不超过8位且不包含空格的字符串)、成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。

输出描述:

对每个测试用例,首先输出1行“Case:”。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3 
时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

输入样例#:

3 1
000007 James 85
000010 Amy 90
000001 Zoe 60

输出样例#:

Case:
000001 Zoe 60
000007 James 85
000010 Amy 90
#include <bits/stdc++.h>
using namespace std;
typedef long long ll; 

struct student{
	char name[10];
	char id[10];
	int grade;
}stu[20000];

bool cmp1(student a,student b){
	return strcmp(a.id,b.id)<0;
}

bool cmp2(student a,student b){
	if(strcmp(a.name,b.name)==0) 
		return strcmp(a.id,b.id)<0;
	else 
		return strcmp(a.name,b.name)<0;
}

bool cmp3(student a,student b){
		if(a.grade==b.grade) 
			return strcmp(a.id,b.id)<0;
	    else 
			return a.grade<b.grade;
}



int main(){
	int n,C;
	cin>>n>>C;
		for(int i= 0;i<n;i++){
		getchar();
			cin>>stu[i].id>>stu[i].name>>stu[i].grade;
		}
			
		switch(C){
			case 1:
				stable_sort(stu,stu + n,cmp1);
				break;
			case 2:
				stable_sort(stu,stu + n,cmp2);
				break;
			case 3:
				stable_sort(stu,stu + n,cmp3);
				break;
			default:
				break;
				}
		    cout<<"Case:"<<endl; 
			for (int i = 0;i<n;i++)
				
			    cout << stu[i].id<<" "<<stu[i].name<<" "<<stu[i].grade<<endl;
		return 0;
}


特殊排序

题目描述

输入一系列整数,将其中最大的数挑出(如果有多个,则挑出一个即可),并将剩下的数进行排序,如果无剩余的数,则输出-1。

输入描述:

输入第一行包括1个整数N,1<=N<=1000,代表输入数据的个数。
接下来的一行有N个整数。

输出描述:

可能有多组测试数据,对于每组数据,
第一行输出一个整数,代表N个整数中的最大值,并将此值从数组中去除,将剩下的数进行排序。
第二行将排序的结果输出。

输入样例#:

4
1 3 4 2

输出样例#:

4
1 2 3
#include <bits/stdc++.h>
using namespace std;
typedef long long ll; 

int main(){
	int n;
	int a[1009];
	while(cin>>n){
		for (int i= 0;i<n;i++) 
			cin>>a[i];
			
		sort(a,a+n);
		
		cout<<a[n-1]<<endl;//输出最大值 
		
		for (int i= 0;i<n-1;i++) //对去掉最大值剩下的数进行排序 
			cout<<a[i]<<" ";
			cout<<endl;
			
			
	}
	return 0;

	}
	

成绩排序3.0

题目描述

有N个学生的数据,将学生数据按成绩从低到高排序,如果成绩相同则按姓名字符的字典序排序,如果姓名的字典序也相同则按照学生的年龄从小到大排序,并输出N个学生排序后的信息。

输入描述:

测试数据有多组,每组输入第一行有一个整数N(N<=1000),接下来的N行包括N个学生的数据。
每个学生的数据包括姓名(长度不超过100的字符串)、年龄(整形数)、成绩(小于等于100的正数)。

输出描述:

将学生信息按成绩进行排序,成绩相同的则按姓名的字母序进行排序。
然后输出学生信息,按照如下格式:
姓名 年龄 成绩

学生姓名的字母序区分字母的大小写,如A要比a的字母序靠前(因为A的ASC码比a的ASC码要小)。

输入样例#:

3
abc 20 99
bcd 19 97
bed 20 97

输出样例#:

bcd 19 97
bed 20 97
abc 20 99
#include <bits/stdc++.h>
using namespace std;
typedef long long ll; 

struct student{
	int grade;
	char name[100];
	int age;
}stu[1000];

bool cmp(student a,student b){
	if (a.grade==b.grade) return strcmp(a.name,b.name)<0;
	else if(strcmp(a.name,b.name)==0) return a.age<b.age;
	else return a.grade <b.grade;
}

int main(){
	int n;
	while(cin>>n){
		for(int i = 0;i<n;i++)
			cin>>stu[i].name>>stu[i].age>>stu[i].grade;
			
		sort(stu,stu + n,cmp);
		for(int i = 0;i<n;i++)
			cout<<stu[i].name<<" "<<stu[i].age<<" "<<stu[i].grade<<endl;
	}
	return 0;
}

大整数排序

题目描述

对N个长度最长可达到1000的数进行排序。

输入描述:

输入第一行为一个整数N,(1<=N<=100)。
接下来的N行每行有一个数,数的长度范围为1<=len<=1000。
每个数都是一个正数,并且保证不包含前缀零。

输出描述:

可能有多组测试数据,对于每组数据,将给出的N个数从小到大进行排序,输出排序后的结果,每个数占一行。

输入样例#:

3
11111111111111111111111111111
2222222222222222222222222222222222
33333333

输出样例#:

33333333
11111111111111111111111111111
222222222222222222222222222222
#include <bits/stdc++.h>
using namespace std;
typedef long long ll; 

bool cmp(string a,string b){
	if (a.length()==b.length())
		return a<b;
	else return  a.length() < b.length();
}

int main(){
	int n;
	string s[1005];
	while(cin>>n){
		for(int i = 0;i<n;i++)
			cin>>s[i];
			sort(s,s+n,cmp);

		for (int i = 0;i<n;i++)
			cout<<s[i]<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_51933492/article/details/127146051
今日推荐