zoukankan      html  css  js  c++  java
  • STL模板中的map的使用与例题

          最近的计分赛,记得自己的都只是过了两题。遇到了两次map,自己在寒假看了一点的map,只知道在字符串匹配的时候可以用的到。但是自己对map的使用还是不够熟练使用,这回在第一次和第二次的计分赛中都遇到可以用map快速写出的AC题目。而且代码精简。

         map是一种二叉树的数据存储结构。map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的。

         map的特点:  1、存储Key-value对
                          2、支持快速查找,查找的复杂度基本是Log(N)
                          3、快速插入,快速删除,快速修改记
    一、map的构造函数
    map共提供了6个构造函数,这块涉及到内存分配器这些东西,不太清楚,在下面我们将接触到一些map的构造方法,这里要说下的就是,我们通常用如下方法构造一个map:
    map<string,int>mp;     //这里的mp就是自己取的名字。定义map类型的变量mp

    还可以自己定义的map<int.int>mp;

    map<string ,int>mapstring;                map<int,string >mapint;
    map<sring,char>mapstring;               map< char ,string>mapchar;
    map<char,int>mapchar;                     map<int ,char>mapint;

    二、数据的插入(与插入的循序无关,自动排序)

    第一种:用insert函数插入pair数据。

    #include <iostream>
    #include<string.h>
    #include<map>
    using namespace std;
    
    int main()
    {
        map<int,string>mp;
        mp.insert(pair<int,string>(3,"student_three"));
        mp.insert(pair<int,string>(1,"student_one"));
        mp.insert(pair<int,string>(2,"student_two"));
    
    
        map<int,string>::iterator iter;
        for(iter=mp.begin();iter!=mp.end();iter++)
             cout<<iter->first<<"   "<<iter->second<<endl;
        return 0;
    }

    第二种:用数组方式插入数据,下面举例说明

    #include <map>
    #include <string.h>
    #include <iostream>
    using namespace std;
    int main()
    {
           map<int, string> mp;
           mp[1]= "student_one";
           mp[2]= "student_two";
           mp[3]= "student_three";
           map<int, string>::iterator  iter;
           for(iter=mapStudent.begin(); iter!= mapStudent.end();iter++)
           {
              cout<<iter->first<<"   "<<iter->second<<endl;
           }
    }

    三、map的大小
    在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:
     
    int nSize = mapStudent.size();  
     
     
    四、数据的遍历
    这里也提供多种方法,对map进行遍,目前自己只学会其中一种。
    #include <map>
    #include <string>
    #include <iostream>
    using namespace std;
    int main()
    {
           map<int, string> mapStudent;
           mapStudent.insert(pair<int, string>(1, "student_one"));
           mapStudent.insert(pair<int, string>(2, "student_two"));
           mapStudent.insert(pair<int, string>(3, "student_three"));
           map<int, string>::reverse_iterator  iter;
           for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)
           {
              cout<<iter->first<<"   "<<iter->second<<endl;
           }
    }

    五、例题

    (1)MD5算法

    MD5是一种信息摘要算法,它可以对任意大小的文件产生等长的密钥,当你在A主机使用MD5得到文件X的密钥后,在B主机同样对文件X使用MD5所得到密钥一定与A主机所得到的密钥相同。然后请实现MD5算法。
    是的,我在开玩笑。
    恩,我实现了一个MD6算法,它可以实现类似的功能。


    本题包含多组样例。
    输入第一行为数字N和Q,N为映射的行数,Q为询问的行数。
    映射中每行包含一个字符串A(0<alen<30),和字符串A使用MD6算法对应的数字。
    询问每行包含一个字符串A。

    输出每个询问行中每个字符串使用MD6算法对应的数字。

    5 3
    fs3fwe 3
    4838fdeewerwer 54
    irjfhid 888
    847hhhh 1
    0000 0
    0000
    847hhhh
    fs3fwe

    0
    1
    3

    #include <iostream>
    #include<map>
    #include<string.h>
    #include<cstdio>
    using namespace std;
    
    int main()
    {
        map<string,int>mp;
        int N,M,i,num;
        string str1,str2;;
        while(scanf("%d%d",&N,&M)!=-1)
        {
            mp.clear();    //一定不要忘记了把map清空
            for(i=0;i<N;i++)
                {
                    cin>>str1>>num;
                    mp[str1]=num;
                }
                for(i=0;i<M;i++)
                {
                    cin>>str2;
                    cout<<mp[str2]<<endl;
                }
        }
        return 0;
    }

    (2)例2

    某次张国庆脑袋抽筋时想到了n个自然数,每个数均不超过1500000000(1.5*109)。已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果。

        输入包含n+1行:
        第1行是整数n,表示自然数的个数。
        第2~n+1行每行一个自然数。

    输入
    8
    2
    4
    2
    4
    5
    100
    2
    100

    输出
    2 3
    4 2
    5 1
    100 2

    #include <iostream>
    #include<map>
    #include<cstdio>
    #include<string.h>
    using namespace std;
    
    int main()
    {
        map<int,int>mp;
        long long n,num1;
        cin>>n;
        while(n--)
       {
           cin>>num1;
           mp[num1]++;
       }
       map<int,int>::iterator iter;
       for(iter=mp.begin();iter!=mp.end();iter++)
          cout<<iter->first<<" "<<iter->second<<endl;
    
        return 0;
    }

    同时题解给出了常规求出

    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    long f[200010];
    
    int main()
    {
        long n;
        cin >> n;
        for (long i=0;i<n;++i)
            cin >> f[i];
        f[n] = -1;
        long num = 1;
        sort(f, f + n);
        for (long i=0;i<n;++i)
        {
            if (f[i] == f[i + 1])
                ++num;
            else {
                cout << f[i] << " " << num << endl;
                num = 1;
            }
        }
        return 0;
    }


    (3)例三

    Description

    得克萨斯州的一个小镇Doubleville,被外星人攻击。他们绑架了当地人并把他们带到飞船里。经过一番(相当不愉快的)人体实验,外星人克隆了一些 受害者,并释放了其中的多个副本回Doubleville。所以,现在有可能发生有6个人:原来的人和5个复制品都叫做Hugh F. Bumblebee。现在FBUC美国联邦调查局命令你负责确定每个人被复制了多少份,为了帮助您完成任务,FBUC收集每个人的DNA样本。同副本和原 来的人具有相同的DNA序列,不同的人有不同的序列(我们知道,城里没有同卵双胞胎,这不是问题)

    Input

    输入中含有多组数据,每一组以一行n m开始,表示共有n个人1 ≤ n ≤ 20000,其中DNA序列长度为m, 1 ≤ m ≤ 20. 接下来的n行为DNA序列:每行包含m个字符,字符为'A','C','G'或'T'。 输入以n=m=0 结尾。

    Output

    每一组数据应输出n行,每行一个整数。第一行表示有几个人没有被复制,第二行表示有几个人只被复制一次(也就是说有两个相同的人),第三行表示有几个是被 复制两次,依次类推,第i行表示其中有i个相同的人的共有几组。举例来说,如果有11个样本,其中之一是John Smith,和所有其余的都是从Joe Foobar复制来的副本,那么你必须打印第一行和第10行输出1,其余行输出0。 

    Sample Input

    9 6
    AAAAAA
    ACACAC
    GTTTTG
    ACACAC
    GTTTTG
    ACACAC
    ACACAC
    TCCCCC
    TCCCCC
    0 0

    Sample Output

    1
    2
    0
    1
    0
    0
    0
    0
    0

     

    可以使用常规的结构体

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    struct dna
    {
      char ch[21];      
    }
     DNA[21000];
     
    int cnt[21000];
     
    int cmp(const void *a,const void *b)
    {
      struct dna *x = (struct dna *)a;
      struct dna *y = (struct dna *)b;
      return strcmp(x->ch,y->ch);   
    }
     
    int main()
    {
      int num,len,i,t;
         
        while(scanf("%d%d",&num,&len)&& (num + len))
        {
            for(i= 0 ; i < num ; ++i)
            {
                  scanf("%s",DNA[i].ch);                             
                  cnt[i+1]= 0;
            } 
             
            qsort(DNA,num,sizeof(DNA[0]),cmp);
             
            t = 1;
            for(i= 1 ; i < num ; ++i)
            {
                if(!strcmp(DNA[i].ch,DNA[i-1].ch))     
                ++t;
                else
                {
                   cnt[t]++;
                   t= 1;     
                } 
            }        
            cnt[t]++;
            for(i= 1 ; i <= num ; ++i)
            printf("%d
    ",cnt[i]);
        }
         
        return 0;
    }

     

     

    这个可以想到的是map;STL中提供的map相当不错。

    #include <iostream>
    #include<map>
    #include<string>
    #include <cstdio>
     using namespace std;
      
     map<string,int>m;
     int cnt[21000];
      
     int main()
     {
           string str;
           int i,num,len;
            
           while(scanf("%d%d",&num,&len)&&( num + len ))        
           {
              for(i = 0 ; i < num ; ++i)
              {
                    cin>>str;                             
                    m[str]++;
                    cnt[i+1] = 0;
                    str.clear();//一定要清空
              }             
               
              map<string,int>::iterator it; 
               
              for( it = m.begin();it != m.end(); ++it)
               cnt[it->second]++;
              
              for(i= 1 ; i <= num ; ++i)
              printf("%d
    ",cnt[i]);
              m.clear();
           }
           return 0;
     }
  • 相关阅读:
    057.Python前端Django模型ORM多表查询
    056.Python前端Django模型ORM多表基本操作
    055.Python前端Django模型ORM
    054.Python之Ubuntu安装Pycharm
    053.Python前端Django框架模板层
    052.Python前端Django框架路由层和视图层
    基数排序
    链表k个节点反向
    链表排序
    函数返回局部指针变量是否可行?
  • 原文地址:https://www.cnblogs.com/chengxs/p/5300288.html
Copyright © 2011-2022 走看看