c++map容器问题,可能是迭代器失效

xiao_mu_mu 2014-01-19 11:33:06
主要是发现输出容器中键值,多了一些与if判断标准不相符的值。我第二个程序的逻辑和第一个程序的逻辑是一样的,第二个程序能够输出正确的结果,第二个输出容器中键值,多了一些与if判断标准不相符的值。恳请大家麻烦帮我看看~我想找出原因是哪里~
之前我是用:
contig2read_iter = contig2read.find(contig);
if(contig2read_iter == contig2read.end())
来判断contig是否在容器里面,后来我改成了:
pair<map<string, cr>::iterator, bool> retu = contig2read.insert(make_pair(contig, wc));
来判断insert操作的返回值。这样做的话,结果就是符合预期的。可以麻烦看看么,我想找出哪里出错了,好避免下次不再犯
谢谢大家了~我自己也没搞清到底是哪里出了问题。

我需要解决的问题是:
处理一个文本文件,每一行中有若干个单词(即代码中的变量gi)和一个标志(代码中的变量contig),统计每一行的每一个单词出现的个数(代码中用容器gi_map进行处理)。就是看包含同一个标志(即contig)的行中所有单词出现的个数。若包含contig标志的所有行中都是同一个标志时,则tag == 1,否则tag == 0(不知我说清,还请见谅~)
我用++(contig2read_iter->second.reads);对每一个contig来说,进行总的gi的数目统计。
主要是发现contig2read_iter->second.reads和每一个contig对应值中的容器map<string, int> gi_map;的总数不相等。
所以我定义一个容器contig2read;用来进行操作
typedef struct cr{
string contig;
string gi;
map<string, int> gi_map;
bool tag;
int reads;
float chimerity_rate;
string::size_type length;
}cr;
map<string, cr> contig2read;


之前的版本:
  while(getline(fin_sam, line))
{
if(line[0] == ' ' || line[0] == '\t' || line[0] == '\n' || line[0] == '@')
{
continue;
}
else
{
//cout << line << endl;
i = 0;
tabnum = 0;
//这里主要获得每一行的相关值
while(tabnum < 2) //here tab is "|"
{
if(line[i] == '|')
{
tabnum++;
}
++i;
}
gi.assign(line, 0, i);
//cout << reads << endl;
i = 0;
tabnum = 0;
k = 0;
while(tabnum < 11)
{
if(line[i] == '\t')
{
++tabnum;
if(tabnum == 2)
{
k = i;
}
if(tabnum == 3)
{
contig.assign(line, k + 1, i - k - 1);
if(contig == "*" || contig == "0")
{
break;
}
}
if(tabnum == 5)
{
map_quality.assign(line, i + 1, 1);
if(map_quality == "*" || map_quality == "0")
{
break;
}
}
if(tabnum == 11)
{
unique_tag.assign(line, i + 1, 6);
break;
}
}
++i;
if(i < line.size())
{
continue;
}
else
{
unique_tag.clear();
break;
}
}
if(contig == "*" || contig == "0" || map_quality == "*" || map_quality == "0")
{
unique_tag.clear();
continue;
}
else if(unique_tag == "XT:A:U")
{
//如果满足相关的条件
contig2read_iter = contig2read.find(contig);

if(contig2read_iter == contig2read.end())
{
//看看行中的contig是否已经加入map容器
wc.contig = contig;
wc.tag = 1;
wc.gi = gi;
wc.reads = 1;
wc.gi_map.insert(make_pair(gi, 1));
contig2read.insert(make_pair(contig, wc));
}
else
{
//看看行中的contig是否已经加入map容器
if(1 == contig2read_iter->second.tag)
{
//对gi进行判断,看看是否已经在容器中
if(gi == contig2read_iter->second.gi)
{
++(contig2read_iter->second.reads);
contig2read_iter->second.gi_map_iter = (contig2read_iter->second.gi_map).find(gi);
++(contig2read_iter->second.gi_map_iter->second);
}
else
{
++(contig2read_iter->second.reads);
contig2read_iter->second.gi_map_iter = (contig2read_iter->second.gi_map).find(gi);
if(contig2read_iter->second.gi_map_iter == contig2read_iter->second.gi_map.end())
{
contig2read_iter->second.gi_map.insert(make_pair(gi, 1));
}
else
{
++(contig2read_iter->second.gi_map_iter->second);
}
contig2read_iter->second.tag = 0;
}
}
else
{
++(contig2read_iter->second.reads);
contig2read_iter->second.gi_map_iter = (contig2read_iter->second.gi_map).find(gi);
if(contig2read_iter->second.gi_map_iter == contig2read_iter->second.gi_map.end())
{
contig2read_iter->second.gi_map.insert(make_pair(gi, 1));
}
else
{
++(contig2read_iter->second.gi_map_iter->second);
}
}
}
}
else
{
unique_tag.clear();
continue;
}
}
}


之后的版本:
  while(getline(fin_sam, line))
{
if(line[0] == ' ' || line[0] == '\t' || line[0] == '\n' || line[0] == '@')
{
continue;
}
else
{
//cout << line << endl;
i = 0;
tabnum = 0;
while(tabnum < 2) //here tab is "|"
{
if(line[i] == '|')
{
tabnum++;
}
++i;
}
gi.clear();
gi.assign(line, 0, i);
//cout << reads << endl;
i = 0;
tabnum = 0;
k = 0;
while(tabnum < 11)
{
if(line[i] == '\t')
{
++tabnum;
if(tabnum == 2)
{
k = i;
}
if(tabnum == 3)
{
contig.assign(line, k + 1, i - k - 1);
if(contig == "*" || contig == "0")
{
break;
}
}
if(tabnum == 5)
{
map_quality.assign(line, i + 1, 1);
if(map_quality == "*" || map_quality == "0")
{
break;
}
}
if(tabnum == 11)
{
unique_tag.clear();
unique_tag.assign(line, i + 1, 6);
break;
}
}
++i;
if(i < line.size())
{
continue;
}
else
{
unique_tag.clear();
break;
}
}
if(contig == "*" || contig == "0" || map_quality == "*" || map_quality == "0")
{
unique_tag.clear();
continue;
}
else if(unique_tag == "XT:A:U")
{
wc.contig = contig;
wc.tag = true;
wc.gi = gi;
wc.reads = 1;
pair<map<string, cr>::iterator, bool> retu = contig2read.insert(make_pair(contig, wc));
if(retu.second)
{
pair<map<string, int>::iterator, bool> ret = retu.first->second.gi_map.insert(make_pair(gi, 1));
}
else
{
if(retu.first->second.tag == true)
{
++retu.first->second.reads;
pair<map<string, int>::iterator, bool> ret = retu.first->second.gi_map.insert(make_pair(gi, 1));
if(ret.second)
{
retu.first->second.tag = false;
}
else
{
++ret.first->second;
}
}
else
{
++retu.first->second.reads;
pair<map<string, int>::iterator, bool> ret = retu.first->second.gi_map.insert(make_pair(gi, 1));
if(ret.second)
{
continue;
}
else
{
++ret.first->second;
}
}
}
}
else
{
continue;
}
}
}
...全文
603 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
minchieh_fay 2014-01-31
  • 打赏
  • 举报
回复
gun->gnu
minchieh_fay 2014-01-31
  • 打赏
  • 举报
回复
不好意思,你的代码太多,不仔细看了,你看下下面我说的2条,是否中招: 1.map的insert不会覆盖原先的值,即key存在时,insert无效 2.linux和mac等gun的系统,insert和erase的返回值不是迭代器,win下才是
赵4老师 2014-01-28
  • 打赏
  • 举报
回复
模板是语法糖。 语法糖越甜,编译调试查错越苦!
ryfdizuo 2014-01-27
  • 打赏
  • 举报
回复
代码可以重写了,为何不用switch case?
buyong 2014-01-27
  • 打赏
  • 举报
回复
引用 3 楼 xiao_mu_mu 的回复:
之前我是用: contig2read_iter = contig2read.find(contig); if(contig2read_iter == contig2read.end()) 来判断contig是否在容器里面,后来我改成了: pair<map<string, cr>::iterator, bool> retu = contig2read.insert(make_pair(contig, wc)); 来判断insert操作的返回值。这样做的话,结果就是符合预期的。可以麻烦看看么,我想找出哪里出错了,好避免下次不再犯
你的第一种是正确的。 第二种是插入一个新元素(如果原来没有),当然之后是每次都有。不知你的程序是不是这个逻辑
漫步者、 2014-01-20
  • 打赏
  • 举报
回复
想表达什么,你的问题是什么?
xiao_mu_mu 2014-01-20
  • 打赏
  • 举报
回复
我再检查检查,谢谢你的关注
xiao_mu_mu 2014-01-20
  • 打赏
  • 举报
回复
嗯,他们说到的也只是导致我程序出错的可能的原因。输出的文本也太大了,有十几二万行,我用少量数据结果输出正确,把整个文本作为输入,就出错了。
漫步者、 2014-01-20
  • 打赏
  • 举报
回复
引用 5 楼 ganpengjin1 的回复:
[quote=引用 4 楼 xiao_mu_mu 的回复:] 也就是,我用了两种不同的方法来判断contig是否在map容器中,前面那种之前有请教说是可能迭代器失效,我找不出原因
不会,如果没有找到就到end了,别人说失效,你就认为失效?失效是你对你的迭代器进行删除或者其他的操作后,让其不再指向某个合法的地址,这样就会失效出错。 明显你的find不会的。[/quote] 还有要注意,你不要在到了end之后还去进行你的迭代器操作(++)了,结果你懂的。
漫步者、 2014-01-20
  • 打赏
  • 举报
回复
引用 4 楼 xiao_mu_mu 的回复:
也就是,我用了两种不同的方法来判断contig是否在map容器中,前面那种之前有请教说是可能迭代器失效,我找不出原因
不会,如果没有找到就到end了,别人说失效,你就认为失效?失效是你对你的迭代器进行删除或者其他的操作后,让其不再指向某个合法的地址,这样就会失效出错。 明显你的find不会的。
xiao_mu_mu 2014-01-20
  • 打赏
  • 举报
回复
也就是,我用了两种不同的方法来判断contig是否在map容器中,前面那种之前有请教说是可能迭代器失效,我找不出原因
xiao_mu_mu 2014-01-20
  • 打赏
  • 举报
回复
之前我是用: contig2read_iter = contig2read.find(contig); if(contig2read_iter == contig2read.end()) 来判断contig是否在容器里面,后来我改成了: pair<map<string, cr>::iterator, bool> retu = contig2read.insert(make_pair(contig, wc)); 来判断insert操作的返回值。这样做的话,结果就是符合预期的。可以麻烦看看么,我想找出哪里出错了,好避免下次不再犯
xiao_mu_mu 2014-01-19
  • 打赏
  • 举报
回复
大致的逻辑是: while() { 对contig是否在容器contig2read进行判断; if(contig不在contig2reads map容器中的话) { 则表示第一次加入,插入wc的内容 } else//表示contig已经在contig2read中 { if(tag==1) { 插入gi,若gi和已经在contig2read中的contig相等则相应的++retu.first->second.reads; 若没有,则表示是一个不同的单词,则tag = 0;并且插入gi,然后++retu.first->second.reads; } else { 插入gi,若gi和已经在contig2read中的contig相等则相应的++retu.first->second.reads; 若没有,则表示是一个不同的单词,则tag = 0;并且插入gi,然后++retu.first->second.reads; } } }

64,685

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧