2、以自定義struct或struct指針作為map的Key


若干問題

 

struct Node {
    int k, b;
    friend bool operator <(Node a, Node b) {
        return a.k < b.k;
    }
}node1, node2;

map<Node, int> mp;


int main() {

    node1.k = 1;
    node1.b = 1;
    mp[node1] = 1;
    node1.k = 1;
    node1.b = 2;
    printf("%d\n", mp.count(node1));
    //輸出1
    return 0;
}
View Code

 

struct Node {
    int k, b;
    friend bool operator <(Node a, Node b) {
        if (a.k != b.k) return a.k < b.k;
        else return a.b < b.b;
    }
}node1, node2;

map<Node, int> mp;


int main() {

    node1.k = 1;
    node1.b = 1;
    mp[node1] = 1;
    node1.k = 1;
    node1.b = 2;
    printf("%d\n", mp.count(node1));
    //輸出0
    return 0;
}
View Code

 

 

 

1、以結構體為Key

map內部自建一顆紅黑樹(一種非嚴格意義上的平衡二叉樹),紅黑樹具有對數據自動排序(默認是以less<>升序對元素排序(排序准則也可以修改))的功能,因此在map內部所有的關鍵字都是有序的。當key為基本數據類型時,不存在問題。但是當關鍵字是一個結構體時,涉及到排序就會出現問題,因為它沒有小於號操作,insert等函數在編譯的時候就會出錯,下面給出解決這個問題的方法:

對操作符"<"進行重載(不可以重載大於號)

#include <map>
#include <iostream>
#include <string>
using namespace std;
struct Node{
    int id;
    string  name;
    friend bool operator < (Node a,Node b) 
    {
        //指定排序策略,按id排序,如果id相等的話,按name排序
        if (a.id != b.id) return a.id > b.id;
        else return a.name > b.name;
    }
}StudentInfo, *pStudentInfo;  //學生信息

int main(){
    int nSize;
    //用學生信息映射分數
    map<Node, int> mapStudent;
    map<Node, int>::iterator it;
    
    StudentInfo.id = 1;
    StudentInfo.name = "student_one";
    mapStudent.insert(pair<Node, int>(StudentInfo, 90));
    StudentInfo.id = 1;
    StudentInfo.name = "student_two";
    mapStudent.insert(pair<Node, int>(StudentInfo, 80));

    for (it = mapStudent.begin(); it != mapStudent.end(); it++)
        cout << it->first.id << " " << it->first.name << " " << it->second << endl;

}

 

printf("%d",mp.find(StudentInfo)->second);
printf("%d",mp[StudentInfo]);  都可以

 

重載的部分可以寫到結構體外,但有三點要求:

1、把friend去掉,把小於號改成一對小括號。

2、用struct把函數包裝起來。

3、map的定義方式改為map<Node, int, cmp> mapStudent;

如:

#include <map>
#include <iostream>
#include <string>
using namespace std;
struct Node{
    int id;
    string  name;
    
}StudentInfo, *pStudentInfo;  //學生信息

struct cmp {
    bool operator () (Node a, Node b)
    {
        //指定排序策略,按nID排序,如果nID相等的話,按strName排序
        if (a.id != b.id) return a.id > b.id;
        else return a.name > b.name;
    }
};
map<Node, int, cmp> mapStudent;
map<Node, int, cmp>::iterator it;
int main(){
    int nSize;
    //用學生信息映射分數
    

    
    StudentInfo.id = 1;
    StudentInfo.name = "student_one";
    mapStudent.insert(pair<Node, int>(StudentInfo, 90));
    StudentInfo.id = 1;
    StudentInfo.name = "student_two";
    mapStudent.insert(pair<Node, int>(StudentInfo, 80));

    for (it = mapStudent.begin(); it != mapStudent.end(); it++)
        cout << it->first.id << " " << it->first.name << " " << it->second << endl;

}

 

printf("%d",mp.find(StudentInfo)->second);
printf("%d",mp[StudentInfo]); 也可以

 

 

 

2、以結構體指針為Key,可以不重載<號,因為地址可以比較大小。

但是也可以根據指針指向的內容重載小於號,但此時重載函數必須放在自定義的結構體外面。(原因不詳。。。)

#include <map>
#include <iostream>
#include <cstdio>
using namespace std;

struct Key
{
    int x,y;
}*ptr;

struct CompareKey
{
    bool operator()(Key *in_a, Key *in_b)
    {
        return in_a->x < in_b->x;
    }
};

map<Key *, int, CompareKey> mp;

int main()
{

    for (int i = 0; i < 10; i++)
    {
        Key *k = new Key;
        if(i==6) ptr=k;

        k->x = i;
        k->y = i+1;

        mp.insert(make_pair(k, i));
    }

    map<Key *, int, CompareKey>::iterator it;
    for(it=mp.begin();it!=mp.end();it++){
        if(it->first==ptr){
            printf("%d %d %d\n",it->first->x,it->first->y,it->second);
        }
    }


}

 


免責聲明!

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



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