您好,欢迎来到九壹网。
搜索
您的当前位置:首页std::map使用总结

std::map使用总结

来源:九壹网
std::map使⽤总结

  为了完成《web搜索》课的作业,我奋⽃了两天把层次汇合聚类HAC算法和基于亲和性消息的聚类算法给实现了。为了实现这两个算法,第⼀件事就是把⽂档向量给计算出来。具体⽽⾔就是⽂本集中的索引词构成了向量空间的⼀个维度。这样有m个索引词就构成了m维的特征向量。在构建特征向量的过程中需要频繁使⽤std::map。因为我需要知道⼀个⽂档中这个索引词,出现的概率是多少。⼀下是我的⼀些经验和⼤家分享⼀下:

  1.operator [] 。这个[]的作⽤很⼤,不仅可以把key所对应value的引⽤取出来,还有插⼊的功能。展⽰⼀个基本的使⽤⽅法先:  

using namespace std;...

map elem;....

//insert operation...

//get inserted valuestring keyword;

int freq = elem[keyword];

  这样就可以把map中key对应的value取出来!如果我输⼊的keyword,这个map⾥⾯没有怎么办?这时就使⽤了[]的插⼊功能。如果⽤户填⼊了⼀个map没有的keyword。operator []可以插⼊⼀个新的pair。并调⽤mapped data的构造函数。有代码为证!

1 struct NumIDF 2 {

3 int num;

4 bool showup; 5 NumIDF() 6 {

7 num = 0;

8 showup = false;

9 cout << \"set to 0 and false\" << endl;10 }11 };12 ...

13 map m_IDF;14 //insert elements15 ...

16 //query elements

17 string newKeyword;//这个词m_IDF中没有18 if(!m_IDF[newKeyword].showup)19 {

20 cout << \"construct a new one\" << endl;21 }

  如果把上⾯代码的输出是

set to 0 and falseconstruct new one

  也就是说,当在[]内输⼊了⼀个新的key之后,map可以⾃动添加⼀个新的pair,新pair的key就是输⼊的newkeyword。⽽mapped data就是经过初始化之后的实例。这个功能⾮常好。我以前都是先⽤find函数找⼀下,如果是新的,再⼿动添加。那样的话会⾮常繁琐。  2.map的iterator的使⽤

  说实在的,我⽤iterator⽤的⽐较少。所以犯了⼏个很低级的错误。写在这⾥也给⾃⼰提个醒。我出错的情况是这样的:我想实现⼀个类似下⾯代码要实现的功能。

vector 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::iterator iterI;....

//这是错误的啊!int i = 5;

iterI = iterI + i;//这是错误的啊!

  我想当然的以为,iterator+多少就会往后⾯跳多少。可以编译不过啊!出了⼀⼤堆错!!有⽊有于是我⽤了下⾯的⽅法

1 map m_Tree;

2 map::iterator iterI = m_Tree.begin();

3 map::iterator iterJ; 4 int i = 0;

5 for( ; i < m_Tree.size()-1; ++iterI,i++) 6 {

7 //iterJ = m_Tree.begin(); 8 //advance(iterJ, i+1); 9 iterJ = iterI;10 iterJ++;

11 for(; iterJ != m_Tree.end(); iterJ++)12 {

13 float s = S((iterI->dvmap),(iterJ->dvmap));14 if(s > mostSim)15 {//this is the pair16 mostSim = s;17 sp.s1 = iterI;18 sp.s2 = iterJ;19 }20 }21 }

我想得到iterI所指向的下⼀个元素,于是我采⽤了第9,10⾏的⽅法。其实第7,8⾏的代码也是可以的,只是不如9,10⾏的⾼效!如果你有更好的⽅法可以带到这个功能,请你告诉我哈!

  3.性能⽅⾯,不要让std复制内存,传指针吧!

  在计算⽂档相似性的时候要⽤到⼀个的⽂档向量。这个⼤向量是使⽤了std::vector来处理。在性能⽅⾯我注意到了两点。    1)使⽤reserve申请⾜够多的内存。为push_back做准备

    2)使⽤push_back的时候要注意。如果在函数体内声明了⼀个vector。这个vector的size超⼤。这是你想把它push_back给类的私有成员的时候势必要复制⼤量的内存。  基于上⾯的两点我采⽤了下⾯的⽅法

1 vector dv;

2 pair >::iterator,bool> pr;

3 pr = m_TF_IDF.insert(pair >(filename, dv));4 vector& rkdv = pr.first->second;5 rkdv.reserve(m_IDF.size());

  其中m_TF_IDF是类的私有成员,我现insert了⼀个空的vector。然后把这个空vector的引⽤取出来,如第4⾏所⽰。然后就可以⽤⼤vector的引⽤来push_back新的数据,这样就免去了内存的复制。

  指针的使⽤,在避免内存复制上,指针也是⼀个快捷⾼效的实现⽅式。在我的程序中,不知⼀个地⽅使⽤了前⾯所说的超⼤vector。为了让想⽤vector的⼈都能⽤上他,我把vector的指针传了出来。 我定义了如下所⽰的结构体:

struct dvPair{

string names;

map*> dvmap;};

我传⼊的是vector的指针,⽽不是vector!  也就是这么多了,别没什么了

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务