C++中stl模版中的erase()和end()(和我之前提的问题不一样)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中stl模版中的erase()和end()(和我之前提的问题不一样)相关的知识,希望对你有一定的参考价值。
我有一个以结构体为元素的list做形参的函数,与构建哈夫曼树有关,代码如下,问题写在了对应行的注释里:
typedef struct HFtree_Data_point
char data;
double weight;
bool l_code;
bool r_code;
struct HFtree_Data_point *lchild;
struct HFtree_Data_point *rchild;
struct HFtree_Data_point *parent;
HFdata;
void Creat(HFdata**HFtree,list<HFdata> h) //构建哈夫曼树核心部分
typedef list<HFdata>::iterator iter;
*HFtree = (HFdata*)malloc(sizeof(HFdata));
while(h.size() != 1)
HFdata *temp = (HFdata*)malloc(sizeof(HFdata));
HFdata *lchild = (HFdata*)malloc(sizeof(HFdata));
HFdata *rchild = (HFdata*)malloc(sizeof(HFdata));
iter temp_list_1 = h.begin();
iter it = h.begin();
while(it != h.end()) //查找左孩子
it++;
if((temp_list_1 -> weight) > (it ->weight))
temp_list_1 = it;
iter temp_list_2 = h.begin();
it = h.begin();
while(it != h.end()) //查找右孩子
it++;
if((temp_list_2 -> weight) > (it ->weight) && temp_list_2 != temp_list_1 )
temp_list_2 = it;
*lchild = *temp_list_1;
*rchild = *temp_list_2;
temp_list_1 = h.erase(temp_list_1);
/*问题:前两个循环正常结束,但是到了此句程序就不能继续执行了,不知道是为什么*/
temp_list_2 = h.erase(temp_list_2);
lchild -> parent = temp; //构建
rchild -> parent = temp;
temp -> lchild = lchild;
temp -> rchild = rchild;
temp -> l_code = 0;
temp -> r_code = 1;
h.push_back(*temp);
(*HFtree) -> data = h.front().data; //赋值
(*HFtree) -> weight = h.front().weight;
(*HFtree) -> lchild = h.front().lchild;
(*HFtree) -> rchild = h.front().rchild;
(*HFtree) -> l_code = h.front().l_code;
(*HFtree) -> r_code = h.front().r_code;
(*HFtree) -> parent = h.front().parent;
//end
还望不吝赐教!!!谢谢
如下
1.添加一个判断函数:
bool IsExistIter(iter& itCompare, list<HFdata>& h)
bool bIsExist = false;
for (iter _this_is_temp = h.begin(); _this_is_temp != h.end(); ++_this_is_temp)
if ( _this_is_temp == itCompare )
return true;
break;
return false;
2.安全地,有保护地erase()
// 保障temp_list_1是有效的
if ( IsExistIter(temp_list_1, h))
temp_list_1 = h.erase(temp_list_1);
else
temp_list_1 = h.begin();
// 保障temp_list_2是有效的
if ( IsExistIter(temp_list_2, h))
temp_list_1 = h.erase(temp_list_1);
else
temp_list_1 = h.begin();
// temp_list_2被删除后,还要再次保障temp_list_1是有效的
if ( !IsExistIter(temp_list_1, h))
temp_list_1 = h.begin();
参考技术A 你应该是研究生吧,研究stl了,应该是高手了。c++高级部分我不熟悉,刚刚才起步,以后还请指教。先记住你了。
尝试在 Python 中重写 C++ 代码时出现问题:删除地图中的项目和“vector.erase(vector.end())”
【中文标题】尝试在 Python 中重写 C++ 代码时出现问题:删除地图中的项目和“vector.erase(vector.end())”【英文标题】:Problems when trying to rewrite C++ code in Python: delete item in map and "vector.erase(vector.end())" 【发布时间】:2019-03-05 15:21:16 【问题描述】:我没有 C++ 经验,但最近需要用 Python 重写一个 C++ 项目。我遇到了几个我未能解决的问题,其中一些如下:
问题 1
假设 C++ 代码中有一个映射 sampleMap
和一个整数 anConstant
:
for (typename map <string, vector <pair <unsigned int, int> > >::iterator l = sampleMap.begin(); l != sampleMap.end(); )
if (l->second.size() < anConstant)
typename map <string, vector <pair <unsigned int, int> > >::iterator tmp = l;
tmp = l; ++tmp; sampleMap.erase (l); l = tmp;
else
++l;
在我的理解中,代码的意思是如果值(实际上是向量)的大小小于整数 (anConstant
),则应从映射 sampleMap
中删除 (key, value)
对。
所以我在下面用 Python 重写了代码:
for key, value in sampleMap.copy().items():
if len(value) < anConstant:
del sampleMap[key]
但似乎它没有正常工作。 可能我误解了c++代码的意思,谁能帮我理解c++代码?
问题 2
同样,假设有一个名为sampleMap
的映射,一个名为sampleVector
的向量,两个名为constantOne
和constantTwo
的常量。
for (typename map <string, vector <pair <unsigned int, int> > >::iterator l = sampleMap.begin(); l != sampleMap.end(); ++l)
if (sampleVector.size() - constantOne < constantTwo)
sampleVector.push_back(make_pair <string, unsigned int> (l->first, l->second.size()));
sampleVector.erase(sampleVector.end());
在我的理解中,代码是说在循环映射sampleMap
时,如果满足if
语句中的条件,则将(key, value)
的大小设置为新对并将该对附加到@987654337 @。
但是最后一句我没看懂:好像没有尝试移除向量中的最后一个元素。那么它有什么作用呢?代码运行正常。
请帮助我理解 C++ 代码。谢谢!
================编辑==================
感谢大家的解决方案!
对于问题1,在测试了c++代码和python代码后,我发现python代码运行良好。无论如何,我确定了 c++ 代码的含义,我学到了很多:P
对于问题2,我仍然不知道sampleVector.erase(sampleVector.end())
在这里做了什么,但是我尝试在这里将其重写为del sampleVector[-1]
(删除sampleVector的最后一项)并且输出与输出相同c++ 代码。多么奇怪!我将打开一个新帖子来讨论这个问题,并将在此处提供新链接。
再次感谢大家! :D
【问题讨论】:
我根本不懂python,但sampleMap.copy().items()
看起来应该是sampleMap.items()
,因为你不想修改地图的副本。
我建议您将这些问题作为两个单独的问题发布。只需从这个问题中删除问题 2 并更改标题,然后为问题 2 制作一个新问题。SO 喜欢每个问题一种问题的格式。
旁注:if
的整个第一个分支,在第一个例子中,可以简化为l = sampleMap.erase (l);
为什么您认为您的 python 代码不起作用?你得到什么输出,你期待什么?什么是输入地图?请出示minimal reproducible example
@NathanOliver 因为如果我在迭代期间修改原始地图,那么我会得到一个错误:P 所以我循环复制一个并修改原始地图。
【参考方案1】:
问题 1
你可能只使用dictionary comprehension:
sampleMap = key: value for (key, value) in sampleMap.items() if value[1] > anConstant
问题 2
看起来像未定义的行为。在最好的情况下,sampleVector.erase(sampleVector.end())
什么都不做。
【讨论】:
谢谢!对于问题 2,我尝试在我的 python 代码中删除 sampleVector 的最后一项,然后它运行正确:O 但我同意你的观点,vector.erase(vector.end()) 在 C++ 中应该是未定义的行为。无论如何,我将打开一个新帖子来讨论这个问题。感谢您抽出时间来帮助我! :D以上是关于C++中stl模版中的erase()和end()(和我之前提的问题不一样)的主要内容,如果未能解决你的问题,请参考以下文章
[转] C++ STL中map.erase(it++)用法原理解析
c++ STL map 中erase()后++会指向那个元素?以及erase后map将会自动做啥操作(也就是会怎么变动)?