std::map使用总结
2011-12-08 21:39
344 查看
为了完成《web搜索》课的作业,我奋斗了两天把层次汇合聚类HAC算法和基于亲和性消息的聚类算法给实现了。为了实现这两个算法,第一件事就是把文档向量给计算出来。具体而言就是文本集中的索引词构成了向量空间的一个维度。这样有m个索引词就构成了m维的特征向量。在构建特征向量的过程中需要频繁使用std::map。因为我需要知道一个文档中这个索引词,出现的概率是多少。一下是我的一些经验和大家分享一下:
1.operator [] 。这个[]的作用很大,不仅可以把key所对应value的引用取出来,还有插入的功能。展示一个基本的使用方法先:
这样就可以把map中key对应的value取出来!如果我输入的keyword,这个map里面没有怎么办?这时就使用了[]的插入功能。如果用户填入了一个map没有的keyword。operator []可以插入一个新的pair。并调用mapped data的构造函数。有代码为证!
如果把上面代码的输出是
也就是说,当在[]内输入了一个新的key之后,map可以自动添加一个新的pair,新pair的key就是输入的newkeyword。而mapped data就是经过初始化之后的实例。这个功能非常好。我以前都是先用find函数找一下,如果是新的,再手动添加。那样的话会非常繁琐。
2.map的iterator的使用
说实在的,我用iterator用的比较少。所以犯了几个很低级的错误。写在这里也给自己提个醒。我出错的情况是这样的:我想实现一个类似下面代码要实现的功能。
我想用iterator来实现上面的功能,于是就有了下面悲壮的一幕:
我想当然的以为,iterator+多少就会往后面跳多少。可以编译不过啊!出了一大堆错!!有木有!!!于是我用了下面的方法
我想得到iterI所指向的下一个元素,于是我采用了第9,10行的方法。其实第7,8行的代码也是可以的,只是不如9,10行的高效!如果你有更好的方法可以带到这个功能,请你告诉我哈!
3.性能方面,不要让std复制内存,传指针吧!
在计算文档相似性的时候要用到一个多维的文档向量。这个大向量是使用了std::vector来处理。在性能方面我注意到了两点。
1)使用reserve申请足够多的内存。为push_back做准备
2)使用push_back的时候要注意。如果在函数体内声明了一个vector<float>。这个vector的size超大。这是你想把它push_back给类的私有成员的时候势必要复制大量的内存。
基于上面的两点我采用了下面的方法
其中m_TF_IDF是类的私有成员,我现insert了一个空的vector。然后把这个空vector的引用取出来,如第4行所示。然后就可以用大vector的引用来push_back新的数据,这样就免去了内存的复制。
指针的使用,在避免内存复制上,指针也是一个快捷高效的实现方式。在我的程序中,不知一个地方使用了前面所说的超大vector<float>。为了让想用vector<float>的人都能用上他,我把vector<float>的指针传了出来。 我定义了如下所示的结构体:
我传入的是vector<float>的指针,而不是vector<float>!
也就是这么多了,别没什么了
1.operator [] 。这个[]的作用很大,不仅可以把key所对应value的引用取出来,还有插入的功能。展示一个基本的使用方法先:
using namespace std; ... map<string,int> elem; .... //insert operation ... //get inserted value string keyword; int freq = elem[keyword];
这样就可以把map中key对应的value取出来!如果我输入的keyword,这个map里面没有怎么办?这时就使用了[]的插入功能。如果用户填入了一个map没有的keyword。operator []可以插入一个新的pair。并调用mapped data的构造函数。有代码为证!
struct NumIDF { int num; bool showup; NumIDF() { num = 0; showup = false; cout << "set to 0 and false" << endl; } }; ... map<string,NumIDF> m_IDF; //insert elements ... //query elements string newKeyword;//这个词m_IDF中没有 if(!m_IDF[newKeyword].showup) { cout << "construct a new one" << endl; }
如果把上面代码的输出是
set to 0 and false construct new one
也就是说,当在[]内输入了一个新的key之后,map可以自动添加一个新的pair,新pair的key就是输入的newkeyword。而mapped data就是经过初始化之后的实例。这个功能非常好。我以前都是先用find函数找一下,如果是新的,再手动添加。那样的话会非常繁琐。
2.map的iterator的使用
说实在的,我用iterator用的比较少。所以犯了几个很低级的错误。写在这里也给自己提个醒。我出错的情况是这样的:我想实现一个类似下面代码要实现的功能。
vector<int> a; for(int i = 0; i < a.size()-1; i++) { for(int j = i+1, j < a.size(); j++) { //some operation about i and j } }
我想用iterator来实现上面的功能,于是就有了下面悲壮的一幕:
map<string,int>::iterator iterI; .... //这是错误的啊! int i = 5; iterI = iterI + i; //这是错误的啊!
我想当然的以为,iterator+多少就会往后面跳多少。可以编译不过啊!出了一大堆错!!有木有!!!于是我用了下面的方法
map<string,int> m_Tree; map<string,int>::iterator iterI = m_Tree.begin(); map<string,int>::iterator iterJ; int i = 0; for( ; i < m_Tree.size()-1; ++iterI,i++) { //iterJ = m_Tree.begin(); //advance(iterJ, i+1); iterJ = iterI; iterJ++; for(; iterJ != m_Tree.end(); iterJ++) { float s = S((iterI->dvmap),(iterJ->dvmap)); if(s > mostSim) {//this is the pair mostSim = s; sp.s1 = iterI; sp.s2 = iterJ; } } }
我想得到iterI所指向的下一个元素,于是我采用了第9,10行的方法。其实第7,8行的代码也是可以的,只是不如9,10行的高效!如果你有更好的方法可以带到这个功能,请你告诉我哈!
3.性能方面,不要让std复制内存,传指针吧!
在计算文档相似性的时候要用到一个多维的文档向量。这个大向量是使用了std::vector来处理。在性能方面我注意到了两点。
1)使用reserve申请足够多的内存。为push_back做准备
2)使用push_back的时候要注意。如果在函数体内声明了一个vector<float>。这个vector的size超大。这是你想把它push_back给类的私有成员的时候势必要复制大量的内存。
基于上面的两点我采用了下面的方法
vector<float> dv; pair<map<string,vector<float> >::iterator,bool> pr; pr = m_TF_IDF.insert(pair<string,vector<float> >(filename, dv)); vector<float>& rkdv = pr.first->second; rkdv.reserve(m_IDF.size());
其中m_TF_IDF是类的私有成员,我现insert了一个空的vector。然后把这个空vector的引用取出来,如第4行所示。然后就可以用大vector的引用来push_back新的数据,这样就免去了内存的复制。
指针的使用,在避免内存复制上,指针也是一个快捷高效的实现方式。在我的程序中,不知一个地方使用了前面所说的超大vector<float>。为了让想用vector<float>的人都能用上他,我把vector<float>的指针传了出来。 我定义了如下所示的结构体:
struct dvPair { string names; map<string,vector<float>*> dvmap; };
我传入的是vector<float>的指针,而不是vector<float>!
也就是这么多了,别没什么了
相关文章推荐
- [C++/object c]_[初级]_[std::map容器的使用总结和NSDictionary词典使用总结]
- Map 使用的一些总结
- 【iOS】苹果,百度Map定位使用与总结
- SICP 习题 (2.21)解题总结: map的使用
- std::map的使用方法
- (转)std::map的用法总结
- 使用CXF开发WebService程序的总结(五):基于Map数据类型处理的的客户端和服务端代码的编写
- std::map使用结构体自定义键值
- 使用std::map和std::list存放数据,消耗内存比实际数据大得多
- 自我对Map的使用方法总结与归纳!
- 使用 std::map 查找 IP 范围
- Node.js 中 source map 使用问题总结
- std::map使用出错_Nodeptr _Pnode = _Root();
- 高效的使用stl::map和std::set
- 【iOS】苹果,百度Map定位使用与总结
- C++技术问题总结-第7篇 map、vector、list、deque各自的使用场合
- C++技术问题总结map、vector、list、deque各自的使用场合
- 关联查询resultMap使用规则总结——(十一)
- Java基础学习总结——Map使用相关问题总结
- 使用用户自定义类型作为std::map的…