首页 > 其他分享 >STL在遍历过程中操作地址的改变

STL在遍历过程中操作地址的改变

时间:2023-09-08 10:57:16浏览次数:32  
标签:map 遍历 STL int 地址 set unordered

2023-08-26 09:57:22

start writing 2023.8.26 9:18

又遇到奇怪错误了,其实在打模拟赛(wzOI 2023.8.24 T1)的时候就发现有这个问题了,赛后来研究一下。

以下代码:

//check是一个返回值为 bool 类型的判断函数,S是一个unordered_set<int>
for(int i=1;i<=n;i++){
    int x=i,maxx=0,ans;
    for(int y:S){
        if(!check(x,y))continue;
        S.erase(y);
        x=merge(x,y);
    }
}

看上去是不是很正常,但是如果你用这样的代码跑一遍样例,如果发生了删除操作,那么 \(y\) 就会变成一个很奇怪的值。

原因跟之前差不多,上面的代码经过我的测试基本上可以等效为:

for(int i=1;i<=n;i++){
    int x=i,maxx=0,ans;
    for(auto it=S.begin();it!=S.end();it++){
        int y=*it;
        if(!check(x,y))continue;
        S.erase(y);
        x=merge(x,y);
    }
}

然后在调试的过程中就会出现以下错误:

很清晰的,S.begin() 的地址发生了变化,那么它原来指向的迭代器的地址也就错误了,所以继续迭代就也会返回一个错误值。

经过不是非常严谨的实验,map,unordered_map,set,unordered_set 中用这样的方法遍历并在中途删除元素,.begin() 的地址均可能会发生改变并报错,但边遍历边增加元素似乎并没有发生地址的变化。

实验代码:

//map<int,int> or unordered_map<int,int> S;
for(int i=1;i<=n;i++){
    int x=i,maxx=0,ans;
    for(auto it=S.begin();it!=S.end();it++){
        int y=(*it).first;
        //(or) int y=it->first;
        if(!check(x,y))continue;
        S.erase(y);
        x=merge(x,y);
    }
}

解决方案:

可以先把要删除的元素存起来,遍历完再删除。

queue<int>Q;
for(int i=1;i<=n;i++){
    int x=i,maxx=0,ans;
    for(int y:S){
        if(!check(x,y))continue;
        Q.push(y);
        x=merge(x,y);
    }
    while(!Q.empty())S.erase(Q.front()),Q.pop();
}

end writing 9:56

标签:map,遍历,STL,int,地址,set,unordered
From: https://www.cnblogs.com/NBest/p/17686981.html

相关文章

  • JS基本遍历方法
    for这大概是应用最广的循环语句了吧,简单实用,且大多数时候性能还是在线的,唯一的缺点大概就是太普通,没有特色,导致很多人现在不愿用它。constarray=[4,7,9,2,6];for(constindex=0;index<array.length;index++){constelement=array[index];console.log......
  • 126.STL 之 空间配置器(allocator)
    126.STL之空间配置器(allocator)1.SGI标准的空间配置器,std::allocatorSGI也定义了一个符合部分标准,名为allocator的配置器,但是它自己不使用,也不建议我们使用,主要原因是效率不佳。它只是把C++的操作符::operatornew和::operatordelete做了一层简单的封装而已。2.SGI特殊的......
  • pandas-遍历和迭代
    pandas-遍历和迭代目录pandas-遍历和迭代iterrows()itertuples()借助zip()foriindf备注参考资料遍历数据是最常见的一种方式,pandas同样也可以遍历。iterrows()或itertuples():这两个方法用于遍历DataFrame的行。iterrows()返回一个迭代器,产生索引和行的元组,而itertup......
  • 使用GO 程序指定IP地址访问 http/https 地址 类似curl --resolve XXXIP:PortYYY
    需求,使用GO程序指定IP地址访问http/https地址传入参数:ipAddr//ipv4地址string值serviceUrl//url地址string值hostContainPort//HostHeader是否带url的端口bool值返回值:responseCode//http状态码int类型,Host//request请求HostHeaderstring类型 ......
  • Keil定位常量、变量到指定地址
    一、常量-ROM区域constcharVersion[]__attribute__((at(0x8001000)))={  'M','V','1','0','0'}; 二、变量-RAM区域intval__attribute__((section(".ARM.__at_0x20000004")))=0x00; 三、函数-ROM区域#pra......
  • 前端请求地址含特殊字符"+"后端接收数据显示空格
    问题描述:前端测试Get请求访问,path中的参数含有加号,后端过滤器中使用request.getParameter()方法无法获取。请求地址:http://localhost:8899/bookmark/getByUser?encryData=g3DGtZnczC7SUm+vRvkaYg==后端过滤器中接收参数如图所示,其中查询字符串是request.getQuerySt......
  • 数组与地址,数组名到底是什么?
    (数组与地址,数组名到底是什么?1.问题引出案例:设计一个函数,可以将整形数组的次序调换例如:arr[5]={1,2,3,4,5},输出形式为:arr[5]={5,4,3,2,1}.案例代码://能否可以正常排序?#include<stdio.h>voidreverse(int*arr){ intlen=sizeof(arr)/sizeof(arr[0]); inttop......
  • .NET Core 在其上下文中,该请求的地址无效。
    .NETCore在其上下文中,该请求的地址无效。看了端口,发现没被占用,后来发现是IP地址变了改成正确的IP就可以了。......
  • 独享IP地址的意义和作用
    在当今数字化时代,独享IP地址正在成为越来越多企业和个人关注的话题。它是一种网络技术解决方案,为用户提供独立、专属的IP地址,与其他用户隔离开来。本文将探讨独享IP地址的意义和作用,以及它为用户带来的重要价值。首先,我们来理解独享IP的概念。传统上,许多用户在互联网上使用共享IP地......
  • Modbus协议详解2:通信方式、地址规则、主从机通信状态
    首先我们要清楚:Modbus是一种串行链路上的主从协议,在通信线路上只能有一个主机存在,不会有多主机存在的情况。虽然主机只有一个,但是从机是可以有多个的。Modbus的通信过程都是由主机发起的,从机在接收到主机的请求后再进行响应,从机不会主动进行数据的发送。并且从机之间也不会互相发送......