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 的向量,两个名为constantOneconstantTwo 的常量。

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 中 remove 和 erase 的区别

C++ STL 中 remove 和 erase 的区别

[转] C++ STL中map.erase(it++)用法原理解析

C++ STL中erase函数的用法 求助~~

C++ STL中erase函数的用法 求助~~

c++ STL map 中erase()后++会指向那个元素?以及erase后map将会自动做啥操作(也就是会怎么变动)?