机试笔记5--排序

一.使用sort来进行排序,它的时间复杂度是nlogn,所以能在1s内处理大概30w的数据

    cmp(typename x,typename y)中是可以对x,y进行更改的,并不会影响到数组中的数,这也极大增加了cmp的适用性。

    题型一.成绩排序(要求稳定)

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

            分析:该题的考点是稳定排序,而sort排序是不稳定排序,解决的方法有两个,一是使用stable_sort函数,它的使用方法和sort一样。另一种方法是给每一个输入加一个递增的下标,然后进行二级排序,当值相同时,下标小的排在前面。

        方法一:

           在编写这个代码的过程中遇到了使用stable_sort报错的问题,发现是由于sort只能给int,char进行排序。解决这个问题也很简单,只需要更改cmp函数就可以

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef struct Student
{
    string name;
    int score;
}Student;
bool downCmp(Student x,Student y)
{
    return x.score>y.score;
}
bool upCmp(Student x,Student y)
{
    return x.score<y.score;
}
int main()
{
    int n,flag;
    cin >> n;
    cin >> flag;
    vector<Student> stu;
    Student s;
    for(int i=0;i<n;i++){
      cin >> s.name >> s.score;
      stu.push_back(s);
    }
    int len = stu.size();
    if(flag==0){
      stable_sort(stu.begin(),stu.end(),downCmp);
    }
    else stable_sort(stu.begin(),stu.end(),upCmp);
    for(int i=0;i<stu.size();i++){
      cout << stu[i].name << " "<<stu[i].score<<endl;
    }
    return 0;
}

      方法二:二级排序,在结构体中添加了一个变量num用于记录每一个变量的先后顺序。

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef struct Student
{
    string name;
    int score;
    int num;
}Student;
bool downCmp(Student x,Student y)
{
    if(x.score > y.score)
        return true;
    else if(x.score==y.score)
        return x.num<y.num;
    else return false;
        
}
bool upCmp(Student x,Student y)
{
    if(x.score < y.score)
        return true;
    else if(x.score==y.score)
        return x.num<y.num;
    else return false;
}
int main()
{
    int n,flag;
    cin >> n;
    cin >> flag;
    vector<Student> stu;
    Student s;
    for(int i=0;i<n;i++){
      cin >> s.name >> s.score;
      s.num=i;
      stu.push_back(s);
    }
    int len = stu.size();
    if(flag==0){
      sort(stu.begin(),stu.end(),downCmp);
    }
    else sort(stu.begin(),stu.end(),upCmp);
    for(int i=0;i<stu.size();i++){
      cout << stu[i].name << " "<<stu[i].score<<endl;
    }
    return 0;
}

 题型三.输入n个数进行排序,要求先按奇偶后按从小到大的顺序排序。核心还是在cmp函数上。

#include <iostream>
#include <algorithm>
using namespace std;
bool cmp(int x,int y)
{
    if(x%2>y%2)
        return true;
    else if(x%2==y%2)
        return x<y;
    else return false;
}
int main()
{
    int n;
    cin >> n;
    int num;
    vector<int> arr;
    for(int i=0;i<n;i++){
      cin >> num;
      arr.push_back(num);
    }
    sort(arr.begin(),arr.end(),cmp);
    for(int i=0;i<n;i++){
      cout <<arr[i]<<" ";
    }
    cout << endl;
    return 0;
}

题型四.字符串排序

编写一个程序,将输入字符串中的字符按如下规则排序(一个测试用例可能包含多组数据,请注意处理)。

规则 1 :英文字母从 A 到 Z 排列,不区分大小写。

如,输入: Type 输出: epTy

规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。

如,输入: BabA 输出: aABb

规则 3 :非英文字母的其它字符保持原来的位置。

如,输入: By?e 输出: Be?y

分析:规则一只要在cmp中全部改成大写进行排序就可以

           规则二使用stable_sort就可以

           规则三只要不对非字母进行排序就可以

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
bool cmp(char x,char y)
{
    if('a'<=x&&x<='z') 
        x-='a'-'A';
    if('a'<=y&&y<='z')
        y-='a'-'A';
    return x<y;
}
int main()
{
    char str[1005];
    char t[1005];
    while(gets(str)){
        int j=0;
      for(int i=0;i<strlen(str);i++){
        if(('a'<=str[i]&& str[i]<='z')||('A'<=str[i]&& str[i]<='Z'))
            t[j++]=str[i];
      }
      stable_sort(t,t+strlen(t),cmp);
        int c=0;
      for(int i=0;i<strlen(str);i++){
        if(('a'<=str[i]&& str[i]<='z')||
           ('A'<=str[i]&& str[i]<='Z'))
            str[i] = t[c++]; 
      }
       cout << str<<endl;
    }
    return 0;
}

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

这里要注意的是在cin >> n和getline(cin,arr)之间要加一个getchar,因为cin之后输入缓冲区还有一个'\n'

整个过程如下

运行到 cin>>n,你输入一个数并按回车,cin把这个数给n并换行,此时输入缓冲区还有一个'\n',如果此时getline的话,getline会把这个换行符吞掉并换成'\0'给arr[1],所以arr[1]实际上是个空字符串。排序后这个空字符串会占第一行,所以就会出现隔一行输出排序后结果且少一个字符串的情况。

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

bool cmp(string x,string y)
{
    return x.size() <y.size();
}
int main()
{
    int n;

    while(cin >> n){
        getchar();
      string arr[n];
    int i=0;
      for(;i<n;i++){
        getline(cin,arr[i]);
        if(arr[i]=="stop"){
            break;
        }
      }
      sort(arr,arr+i,cmp);
      for(int j=0;j<i;j++){
        cout << arr[j] <<endl;
      }
    }
    return 0;
}

 

一些特殊的情况

  1.数据量很大,有几百万,这时候,nlogn的sort就无法满足要求了,如果待排数据的大小范围不是太大的话,可以使用简单的计数排序。时间复杂度为O(n)

  2.找出数组中第K大的元素,可以利用快速排序中的分区算法

    

int findK(int K,int a[],int start,int end)
{
    int pos;
    pos = partition(a,start,end);
    if(K>pos+1)
        return findK(K,a,pos+1,end);
    else if(K<pos+1)
        return findK(K,a,start,pos-1);
    else
        return a[pos];
}

 

 

           

posted @ 2020-03-30 20:59  不二良  阅读(194)  评论(0编辑  收藏  举报