map技数,数组计数,结构体计数的相关比较与分析(一)

数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。

输入描述:
先输入键值对的个数
然后输入成对的index和value值,以空格隔开

输出描述:
输出合并后的键值对(多行)

输入例子:
4
0 1
0 2
1 2
3 4

输出例子:
0 3
1 2
3 4
1.map
注意点
http://blog.csdn.net/ycs34082419900527/article/details/62227448?locationNum=1&fps=1
1、ap是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。
数据的插入
1、insert函数插入pair数据
比如:`map

make_pair(1,'@')  
而不必费力的写成  
pair<int ,char>(1,'@')  

2、用insert函数插入value_type

map<int, string> mapStudent;  
mapStudent.insert(map<int, string>::value_type (1, "student_one")
map<int, string>::iterator  iter;  
for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  
   {  
     cout<<iter->first<<" "<<iter->second<<endl;  
   }  

3、用数组方式插入

map<int, string> mapStudent;  
mapStudent[1] =  "student_one";  

但是会覆盖
map的大小
1、

int nSize = mapStudent.size(); 

数据的遍历
1、应用前向遍历器
2.反向遍历器

#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;  
       }  

3、用数组方式:

#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"));  
       int nSize = mapStudent.size()  
//此处有误,应该是 for(int nIndex = 1; nIndex <= nSize; nIndex++)   
//by rainfish  
       for(int nIndex = 0; nIndex < nSize; nIndex++)  
       {  
           cout<<mapStudent[nIndex]<<end;  
       }  
} 

数据的查找
1、用count函数来判定关键字是否出现,缺点是无法定位数据的出现位置。cout的返回值只有两个0或者1
2、用find函数来定位数据出现位置,它返回一个迭代器,当数据出现的时候,他返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。

#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>::iterator iter;  
       iter = mapStudent.find(1);  
       if(iter != mapStudent.end())  
      {  
           cout<<"Find, the value is "<<iter->second<<endl;  
       }  
       Else  
       {  
           cout<<"Do not Find"<<endl;  
       }  
} 

数据的清空与判空
清空map中的数据可以用clear()函数,判定map中是否有数据可以用empty()函数,它返回true则说明是空map
数据的删除
这里要用到erase函数,它有三个重载了的函数,下面在例子中详细说明它们的用法

#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"));  
       //如果你要演示输出效果,请选择以下的一种,你看到的效果会比较好  
       //如果要删除1,用迭代器删除  
       map<int, string>::iterator iter;  
       iter = mapStudent.find(1);  
       mapStudent.erase(iter);  
       //如果要删除1,用关键字删除  
       int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0  
       //用迭代器,成片的删除  
       //一下代码把整个map清空  
       mapStudent.earse(mapStudent.begin(), mapStudent.end());  
       //成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合  
     //自个加上遍历代码,打印输出吧  
}  

排序
这里要讲的是一点比较高深的用法了,排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过不去,下面给出两个方法解决这个问题

#include <map>  
#include <string> 
#include<iostream>
using namespace std;  
typedef struct tagStudentInfo  
{  
       int      nID;  
       string   strName;  
       bool operator < (tagStudentInfo const& _A) const  
       {  
              //这个函数指定排序策略,按nID排序,如果nID相等的话,按strName排序  
              if(nID < _A.nID)  return true;  
              if(nID == _A.nID) return strName.compare(_A.strName) < 0;  
              return false;  
       }  
}StudentInfo;  //学生信息   
int main()  
{  
       int nSize;  
       //用学生信息映射分数  
       map<StudentInfo, int>mapStudent;  
       map<StudentInfo, int>::iterator iter;  
       StudentInfo studentInfo;  
       studentInfo.nID = 1;  
       studentInfo.strName = "student_one" ; 
       mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));  
       studentInfo.nID = 2;  
       studentInfo.strName = "student_two";  
       mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));  
       for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++)  
         cout<<iter->first.nID<<endl<<iter->first.strName<<endl<<iter->second<<endl;  
} 

2、第二种:仿函数的应用,这个时候结构体中没有直接的小于号重载,程序说明

#include <map>  
#include <string> 
#include<iostream>
using namespace std;  
typedef struct tagStudentInfo  
{  
       int      nID;  
       string   strName;  
       //bool operator < (tagStudentInfo const& _A) const  
       //{  
       //       //这个函数指定排序策略,按nID排序,如果nID相等的话,按strName排序  
       //       if(nID < _A.nID)  return true;  
       //       if(nID == _A.nID) return strName.compare(_A.strName) < 0;  
       //       return false;  
       //}  
}StudentInfo;  //学生信息 
class sort  
{  
       public:  
       bool operator() (StudentInfo const &_A, StudentInfo const &_B) const  
       {  
              if(_A.nID < _B.nID) return true;  
              if(_A.nID == _B.nID) return _A.strName.compare(_B.strName) < 0;  
              return false;  
       }  
};  
int main()  
{  
       int nSize;  
       //用学生信息映射分数  
       map<StudentInfo, int,sort>mapStudent;  
       map<StudentInfo, int>::iterator iter;  
       StudentInfo studentInfo;  
       studentInfo.nID = 1;  
       studentInfo.strName = "student_one" ; 
       mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));  
       studentInfo.nID = 2;  
       studentInfo.strName = "student_two";  
       mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));  
       for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++)  
         cout<<iter->first.nID<<endl<<iter->first.strName<<endl<<iter->second<<endl;  
} 

由于STL是一个统一的整体,map的很多用法都和STL中其它的东西结合在一起,比如在排序上,这里默认用的是小于号,即less<>,如果要从大到小排序呢,这里涉及到的东西很多,在此无法一一加以说明。
还要说明的是,map中由于它内部有序,由红黑树保证,因此很多函数执行的时间复杂度都是log2N的,如果用map函数可以实现的功能,而STL Algorithm也可以完成该功能,建议用map自带函数,效率高一些。
下面说下,map在空间上的特性,否则,估计你用起来会有时候表现的比较郁闷,由于map的每个数据对应红黑树上的一个节点,这个节点在不保存你的数据时,是占用16个字节的,一个父节点指针,左右孩子指针,还有一个枚举值(标示红黑的,相当于平衡二叉树中的平衡因子),我想大家应该知道,这些地方很费内存了


#include<iostream>
#include<string>
#include<stack>
#include<vector>
#include<map>

using namespace std;
int main()
    {
    int num;
    int index,value;
    map<int,int> imap;
    cin>>num;
    for(int i=0;i<num;i++)
        {
        cin>>index>>value;
        if(imap.count(index))
            imap[index]+=value;
        else
            imap.insert(make_pair(index,value));

    }
    for(map<int,int>::iterator it=imap.begin();it!=imap.end();it++)
        cout<<it->first<<" "<<it->second<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值