zoukankan      html  css  js  c++  java
  • 数据结构:映射

    我们通常所用的map其实就是一棵红黑树,如果有平衡树问题能够用它来解决一定要用,不要手写了,因为红黑树的效率是非常棒的

    先看几个定义:

    map<string,int> m1;
    map<string,map<string,int> >m2;
    multiset<string> s1;
    multimap<string,string> m3;

    其中m1就是一个关联数组,为了模拟普通哈希表

    (这里的所有的都是用红黑树实现的,如果你想用哈希表实现,请直接把map替换成hash_map,在空间足够的情况下)

    另外,如果有C++11用,一定要用unordered_map,别用hash_map了

    hash_map有一个专有的命名空间:

    using namespace __gnu_cxx;

    m2是二维哈希表

    s1在之前介绍集合的时候没有提到,这里再提一下,这是允许有重复元素的STL集合,学名多级集合

    m3就是一个多级映射,允许一个x对应多个y的情况,这样便于实现字典

    我们一个一个介绍,s1就不介绍了,和set的用法完全一致

    首先是实现最简单的哈希表功能:

        string word;
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>word;
            ++m1[word];
        }
        int m;
        cin>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>word;
            if(m1.count(word))
                cout<<"Yes"<<endl;
            else
                cout<<"No"<<endl;
        }

    我们可以看到完全不用手写哈希了,而且如果你想改哈希函数,那么替换成hash_map之后直接重载就好了,这里就不多介绍了

    如果我们想删除一个键值对,也非常简单,按键删除就行了

        int l;
        cin>>l;
        for(int i=1;i<=l;i++)
        {
            cin>>word;
            m1.erase(word);
        }

    如果你想枚举当前所有的映射情况的话:

        for(map<string,int>::iterator it=m1.begin();it!=m1.end();++it)
            cout<<"key: "<<it->first <<" value: "<<it->second<<endl;

    知道iterator写后面就没问题了

    然后介绍二维哈希表:

        cin>>n;
        for(int i=1;i<=n;i++)
        {
            string t1,t2;
            int num;
            cin>>t1>>t2>>num;
            m2[t1][t2]+=num;
        }
        
            for(map<string,map<string,int> >::iterator it=m2.begin();it!=m2.end();it++)
            {
                cout<<it->first<<",";
                for(map<string,int>::iterator it_2=it->second.begin();it_2!=it->second.end();it_2++)
                {
                    cout<<it_2->first<<":"<<it_2->second<<endl;
                }
            }

    记住这个for循环的操作还是很有必要的,用的时候记得替换成hash_map,不然就是树套树了

    如果你想实现字典的话,要注意的是多级映射不能直接用下标那么赋值,需要Insert的是pair类型的变量

        typedef pair<string,string> dic;
        dic d1("smart","klug");
        dic d2("clever","raffiniert");
        dic d3("smart","seltsam");
        m3.insert(d1);
        m3.insert(d2);
        m3.insert(d3);
        word="smart";
        for(multimap<string,string>::iterator pos=m3.lower_bound(word);pos!=m3.upper_bound(word);++pos)
        {
            cout<<pos->second<<endl;
        }

    这样就可以,下面贴出来完整的代码:

     1 #include<iostream>
     2 #include<map>
     3 #include<string> 
     4 #include<iterator>
     5 #include<set>
     6 using namespace std;
     7 map<string,int> m1;
     8 map<string,map<string,int> >m2;
     9 multiset<string> s1;
    10 multimap<string,string> m3;
    11 int main()
    12 {
    13     string word;
    14     int n;
    15     cin>>n;
    16     for(int i=1;i<=n;i++)
    17     {
    18         cin>>word;
    19         ++m1[word];
    20     }
    21     int m;
    22     cin>>m;
    23     for(int i=1;i<=m;i++)
    24     {
    25         cin>>word;
    26         if(m1.count(word))
    27             cout<<"Yes"<<endl;
    28         else
    29             cout<<"No"<<endl;
    30     }
    31     int l;
    32     cin>>l;
    33     for(int i=1;i<=l;i++)
    34     {
    35         cin>>word;
    36         m1.erase(word);
    37     }
    38     
    39     for(map<string,int>::iterator it=m1.begin();it!=m1.end();++it)
    40         cout<<"key: "<<it->first <<" value: "<<it->second<<endl;
    41     cin>>n;
    42     for(int i=1;i<=n;i++)
    43     {
    44         string t1,t2;
    45         int num;
    46         cin>>t1>>t2>>num;
    47         m2[t1][t2]+=num;
    48     }
    49     
    50         for(map<string,map<string,int> >::iterator it=m2.begin();it!=m2.end();it++)
    51         {
    52             cout<<it->first<<",";
    53             for(map<string,int>::iterator it_2=it->second.begin();it_2!=it->second.end();it_2++)
    54             {
    55                 cout<<it_2->first<<":"<<it_2->second<<endl;
    56             }
    57         }
    58     typedef pair<string,string> dic;
    59     dic d1("smart","klug");
    60     dic d2("clever","raffiniert");
    61     dic d3("smart","seltsam");
    62     m3.insert(d1);
    63     m3.insert(d2);
    64     m3.insert(d3);
    65     word="smart";
    66     for(multimap<string,string>::iterator pos=m3.lower_bound(word);pos!=m3.upper_bound(word);++pos)
    67     {
    68         cout<<pos->second<<endl;
    69     }
    70     return 0;
    71 }

    当你会用这些东西之后,很多以前做不到的东西,就都十分简单了

  • 相关阅读:
    微信支付接口开发时遇到的问题
    记录一次特别瞎的问题。。。
    二叉树的三种遍历(java实现)
    【转】redis实现的分布式锁
    @RequestParam、@ReqeustBody、@ReponseBody认识
    同步、异步、阻塞、非阻塞
    multipart/form-data和application/x-www-form-urlencoded区别
    HTTP请求的502、504、499错误
    Nginx配置CI框架问题(Linux平台下Centos系统)
    mac中更改xampp的根目录
  • 原文地址:https://www.cnblogs.com/aininot260/p/9332794.html
Copyright © 2011-2022 走看看