昨天,我写了一个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. java开发知识IO知识之输入输出流以及文件

    目录 java开发知识IO知识之输入输出流以及文件 一丶流概述 二丶输入流讲解 InputStream类. 1. 输入流以及类层次结构 2.文件操作.使用输入流读取 三丶输出流 OutputStrea ...

  2. sql删除数据库重复字段的行

    要保留的数据: WITH summary AS ( SELECT p.id, p.customer, p.total, ROW_NUMBER() OVER(PARTITION BY p.custome ...

  3. Scrapy-Redis分布式爬虫常规操作

    一.X-path 的常规用法1./是从根节点选取,有顺序2.//从当前节点选择文档中的节点,无顺序3..选取当前节点4...选取当前节点的父节点5.@选取属性6. //div[@class='docl ...

  4. [MySQL] explain中的using where和using index

    1. 查看表中的所有索引 show index from modify_passwd_log;  有两个 一个是id的主键索引 , 一个是email_id的普通索引 2. using index表示 ...

  5. PHP中private、public、protected的区别详解

    先简单粗俗的描述下:public 表示全局,类内部外部子类都可以访问:private表示私有的,只有本类内部可以使用:protected表示受保护的,只有本类或子类或父类中可以访问: 再啰嗦的解释下: ...

  6. Java开发笔记(十二)布尔变量论道与或非

    在编程语言的设计之初,它们除了可以进行数学计算,还常常用于逻辑推理和条件判断.为了实现逻辑判断的功能,Java引入了一种布尔类型boolean,用来表示“真”和“假”.该类型的变量只允许两个取值,即t ...

  7. 环境搭建 - Tomcat(Windows)

    Tomcat环境搭建 本文以Windows7下搭建tomcat-8.5.15为示例 下载tomcat压缩包 网址:Tomcat 非C盘根目录新建文件夹:Tomcat D:\tomcat 将tomcat ...

  8. mixins混入

    mixins混入:定义类,多重继承 使用方法见附件: mixins混入.zip    

  9. Oracle11g: datetime

    --上一月,上一年 select add_months(sysdate,-1) last_month,add_months(sysdate,-12) last_year from dual; --下一 ...

  10. js获取地址栏传参

    地址:http://127.0.0.1:8082/prosperleedir/index.html?id=6666&name=prosper#prosper         Location{ ...