結構體或對象排序


經常碰到結構體排序的問題,在此總結一下。
以一個簡單的例題開始:

例1、有三個人(Person結構體),每個人都有name(string型)和age(int型)兩個屬性,現在需要按照下面的規則排序:先以姓名按從小到大排序(如abc<abd),如果姓名相同,則按照年齡從大到小排序。

#include<iostream>
#include<string>
using namespace std;
struct Person{
    string name;
    int age;
};
void exchange(Person &a,Person &b){
    //注意交換的時候,中間變量是結構體類型,而不是基本數據類型(int,char,string)等。
    Person temp;
    temp=a;
    a=b;
    b=temp;
}
int main(){
    Person p[3];
    int i,j;
    for(i=0;i<3;i++){
        cin>>p[i].name>>p[i].age;
    }
    //冒泡排序實現
    for(i=0;i<3;i++){
        for(j=0;j<3-i-1;j++){
            if(p[j].name>p[j+1].name){
                exchange(p[j],p[j+1]);
            } else if(p[j].name==p[j+1].name){
                if(p[j].age<p[j+1].age){
                    exchange(p[j],p[j+1]);
                }
            }
        }
    }
    //依次輸出
    for(i=0;i<3;i++){
        cout<<p[i].name<<' '<<p[i].age<<endl;
    }
}

 這個代碼是我最初寫的,毫無技術含量,參加過ACM或者程序競賽的朋友一看就知道這樣做太復雜,因為有一個簡單的sort函數,只要一行代碼即可實現。

sort函數首先是一個排序函數,不僅可以用來給數字排序,還可以給字符串排序,默認的是升序,如果需要降序的話,可以自己寫一個cmp回調函數(函數名可自擬,通常用cmp),然后在sort函數中,加上(cmp)函數名即可。

例2、隨機產生10個數,並且從大到小輸出

#include<iostream>
#include<algorithm>
#include<cstdlib>
bool cmp(int a,int b){
    return a>b;
}
using namespace std;
int main(){
    int A[10],i;
    for(i=0;i<10;i++){
        A[i]=rand();
    }
    sort(A,A+10,cmp);
    for(i=0;i<10;i++){
        cout<<A[i]<<' ';
    }
}

 注意:使用sort函數,必須要加#include<algorithm>頭文件。在sort函數中,第一個參數為數組(字符串)名,第二個參數為排序范圍,是從A到A+n(n為長度),第三個參數可省,省略后則代表默認升序,加上自己寫的cmp函數,即可按照cmp中的規定進行排序。

既然sort函數這么神奇,那他肯定也是可以對結構體或者對象進行排序的。比如例1可以用如下代碼:

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
struct Person{
    string name;
    int age;
};
bool cmp(Person a,Person b){
    if(a.name!=b.name){
        return a.name<b.name;
    } else {
        return a.age>b.age;
    }
}
int main(){
    Person p[3];
    int i,j;
    for(i=0;i<3;i++){
        cin>>p[i].name>>p[i].age;
    }
    //排序
    sort(p,p+3,cmp);
    //依次輸出
    for(i=0;i<3;i++){
        cout<<p[i].name<<' '<<p[i].age<<endl;
    }
}

對於稍微簡單的問題便可以用這種方法。如果問題稍復雜,也就是結構體中的屬性太多了,於是在cmp函數中的判斷語句就增加了,此時要注意寫判斷語句的時候一定要弄清楚先判斷什么,在判斷什么,怎么組織語句等。

比如例3、在這里我們需要對N個人(Person)進行排序,規則如下:每個人有3個屬性,name(string型),age(int型),height(int型)。優先按照name由大到小排名,name相同的則按照age由大到小排序,age相同的則按照height由大到小排序。

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
struct Person{
    string name;
    int age;
    int height;
};
bool cmp(Person a,Person b){
    if(a.name!=b.name){
        return a.name>b.name;
    }
    if(a.name==b.name && a.age!=b.age){
        return a.age>b.age;
    }
    if(a.name==b.name && a.age==b.age){
        return a.height>b.height;
    }
}
int main(){
    int n;
    cin>>n;
    Person p[n];
    int i,j;
    for(i=0;i<n;i++){
        cin>>p[i].name>>p[i].age>>p[i].height;
    }
    //排序
    sort(p,p+n,cmp);
    //依次輸出
    for(i=0;i<n;i++){
        cout<<p[i].name<<' '<<p[i].age<<' '<<p[i].height<<endl;
    }
}

 其實,對於結構體或者對象排序時,最關鍵的是寫cmp函數。另外,如果只是對一組數據(一串個數字或者字符串)反向排序后輸出,如果只是關心輸出,則可以取巧,直接用sort函數,不用寫cmp回調函數,直接在輸出的時候,從length-1開始倒序輸出。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM