昨天,我写了一个multiset去重,让tt指向it的后面第一个元素,若重复则删除这2个元素,并令it=tt,it++;来使it指向tt的下一个元素(我想指向原it的后面第2个元素,并认为tt的下一个元素就是原it的后面第2个元素)

 #include<iostream>
 #include<cstdio>
 #include<set>
 using namespace std;

 typedef long long ll;
 multiset<ll> s;
 multiset<ll>::iterator it;
 multiset<ll>::iterator tt;

 int main()
 {
     ll t,n,in;
     cin >> t;
     while (t--)
     {
         s.clear();
         cin >> n;
         ; i<=n; i++)
         {
             cin >> in;
             s.insert(in);
         }

         for(it = s.begin(); it != s.end() && tt != s.end();)
         {
             tt=it;
             tt++;
             if(it == s.end() || tt == s.end())break;
             if(*it == *tt)
             {
                 s.erase(it);
                 s.erase(tt);
                 it = tt;
                 it++;
             }
             else
             {
                 it=tt;
             }
         }
         it = s.begin();
         tt = it;
         tt++;
         printf("%lld %lld\n",*tt,*it);

     }
 }

然而去重失败了

接着我尝试输出每次检测到的元素,发现当检测到2 2后,下一次检测到的是3 4,也就是说程序跳过了3 3.

于是我尝试查看迭代器的地址,发现出现了下面这种情况

(我给ii迭代器模拟it迭代器的情况)

tt指向it后面的一个元素,也就是tt=it;tt++;然后删除元素时,我将ii=tt;ii++;

这时每当ii++时,它的地址从48->88->a8(168),但如果写成it++;it++;的话,it的地址是从28->08->68的,第一个3在68那,但如果是我原来写的方法,这时就访问的到了88,也就是第2个3的位置,也就是跳过了一个元素。

当ii=tt;ii++;后ii指向的不是第一个3,但2次i++后的却是第一个3,这是否和multiset的数据结构有关?

如果是2次i++后结果是正确的

 #include<iostream>
 #include<cstdio>
 #include<set>
 using namespace std;
 ;
 typedef long long ll;
 multiset<ll> s;
 multiset<ll>::iterator it;
 multiset<ll>::iterator tt;
 multiset<ll>::iterator ii;
 int main()
 {
     ll t,n,in;
     cin >> t;
     while (t--)
     {
         s.clear();
         cin >> n;
         ; i<=n; i++)
         {
             cin >> in;
             s.insert(in);
         }

         for(it = s.begin(); it != s.end() && tt != s.end();)
         {
             tt=it;
             tt++;
             if(it == s.end() || tt == s.end())break;
             if(*it == *tt)
             {
                 s.erase(it);
                 s.erase(tt);
                                  it++;
                 it++;
             }
             else
             {
                 it=tt;
             }
         }
         it = s.begin();
         tt = it;
         tt++;
         printf("%lld %lld\n",*tt,*it);
     }
 }

multiset的erase()操作中出现跳过元素的问题的更多相关文章

  1. multiset容器erase函数的误用

    <从缺陷中学习C/C++>第3章库函数问题,本章主要介绍库函数的使用中会遇到的问题.使用库函数可以降低软件开发的难度,提高代码编写的效率.本节为大家介绍multiset容器erase函数的 ...

  2. python删除数组元素导致跳过元素

    复现的情况大概可以写成这样 abc = [1, 2, 2, 3, 4] print abc for index, i in enumerate(abc): if i == 2: del abc[ind ...

  3. js 在array的遍历操作中修改arry中元素数量 出现的一些奇特的操作

    在js中array是属于复杂类型,在arr1=arr2得赋值操作中,arr1得到的值并不是arr2的value,而是一个指向引用.那么修改arr1的同时arr2读取的值也会同步变化,那么问题来了,上代 ...

  4. STL中用erase()方法遍历删除元素 .xml

    pre{ line-height:1; color:#f0caa6; background-color:#2d161d; font-size:16px;}.sysFunc{color:#e54ae9; ...

  5. STL中用erase()方法遍历删除元素

    STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.set.map).在使用erase方法来删除元素时 ...

  6. deque源码4(deque元素操作:pop_back、pop_front、clear、erase、insert)

    deque源码1(deque概述.deque中的控制器) deque源码2(deque迭代器.deque的数据结构) deque源码3(deque的构造与内存.ctor.push_back.push_ ...

  7. STL的erase()陷阱-迭代器失效总结

    下面材料整理自Internet&著作. STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.s ...

  8. C++ Set & MultiSet

    转自http://www.cppblog.com/wanghaiguang/archive/2012/06/05/177627.html STL Set介绍集合(Set)是一种包含已排序对象的关联容器 ...

  9. [STL]set/multiset用法详解[自从VS2010开始,set的iterator类型自动就是const的引用类型]

    集合 使用set或multiset之前,必须加入头文件<set> Set.multiset都是集合类,差别在与set中不允许有重复元素,multiset中允许有重复元素. sets和mul ...

随机推荐

  1. Spring源码情操陶冶-tx:advice解析器

    承接Spring源码情操陶冶-自定义节点的解析.本节关于事务进行简单的解析 spring配置文件样例 简单的事务配置,对save/delete开头的方法加事务,get/find开头的设置为不加事务只读 ...

  2. Spring Boot 2.x (八):日志框架的使用

    我们为啥要用日志? 最初我们开始接触Java的时候,我们通常会使用System.out.println()将我们想要知道的信息打印到控制台. 但是,如果在服务器上我们去运行我们的Java程序,这个时候 ...

  3. Linux常用命令详解(week1_day1_1)--技术流ken

    本节内容 基础命令:lsmanpwdcdmkdirechotouchcpmvrmrmdircatmorelessheadtailclearpoweroffreboot进阶命令(下一章节):aliasu ...

  4. .NET平台下使用Redis

    using DBI.SaaS.Web.Models.Args; using Rafy; using StackExchange.Redis; using System; using System.Co ...

  5. Elasticsearch系列(5):深入搜索

    结构化搜索 结构化搜索是指搜索那些具有内置结构数据的过程,比如日期,时间和数字都是结构化的,它们有精确的格式,我们可以对这些格式进行逻辑操作,比较常见的操作包括比较数字或时间的范围,或判定两个值的大小 ...

  6. 关于火狐和IE下href="javascript:void(0)"兼容性的问题

    今天在开发中发现,使用如下方式的链接.在Chrome中点击后行为符合预期,但在IE下会新开标签卡(根据参考资料,Firefox中有相同问题). 经过排查,发现是href="javascrip ...

  7. html的标签分类————可以上传的数据篇

    html的标签可以分为: 块级标签:div(白板),H系列(加大加粗,H1—H7,字体一般逐渐变小,一般用作标题),p标签(段落之间有间距) 行内标签:span(白板) 此外,标签之间是可以嵌套的.为 ...

  8. Dynamics 365 Online-Security Updates On TLS 1.2

    不仅仅是Dynamics 365,现在MS许多产品都开始主推使用TLS1.2,所以在日常开发中,需要注意这部分的改动. 如果访问某个服务,出现错误信息类似于“Could not create SSL/ ...

  9. pwn with glibc heap(堆利用手册)

    前言 ​ 对一些有趣的堆相关的漏洞的利用做一个记录,如有差错,请见谅. ​ 文中未做说明 均是指 glibc 2.23 ​ 相关引用已在文中进行了标注,如有遗漏,请提醒. 简单源码分析 ​ 本节只是简 ...

  10. 面板JPanel,滚动面板JScrollPane,文本域JTextArea

    [面板JPanel] 面板就是一个容器 每一个容器都可以有一个自己的独立的布局和组件,这些容器之间也不会互相干扰 //导入Java类 import javax.swing.*; import java ...