如何方便地遍历一个顺序可能发生变化的数组?

哈利_蜘蛛侠 2018-08-25 07:46:32
有一个数组aObjectList(也未必是数组,可能是链表形式实现),需要遍历其中所有元素(遍历的顺序不重要),调用各元素的某个方法(比如叫做DoSth())。然后一般的写法是这样:

for(int i = 0; i < aObjectList.Size(); ++i)
{
aObjectList[i].DoSth();
}

然而如果DoSth()的实现中会更改对应对象在数组中的位置的话, 上述操作就出问题了(如果aObjectList不是可以用索引来引用的数组、而是只能获得next或者prev的链表的话,好像还要更麻烦一些)。请问有什么比较好的解决方法吗?
不管解决方法是什么,需要满足如下条件:
1、不能要求DoSth()的实现中不会更改对应元素在数组中的位置;
2、DoSth()的实现中,可以接受不立即执行其中修改元素位置的代码(但是最好还是不要这样做);
3、不能将aObjectList变得过于复杂,并且要尽量减少代码执行的开销。

请问有什么好方法吗?
...全文
435 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
哈利_蜘蛛侠 2019-09-17
  • 打赏
  • 举报
回复
其实针对我遇到的那个具体问题,有一种很神奇的实现方法;不过由于不具有普遍性,所以就不贴上来了。
哈利_蜘蛛侠 2018-08-28
  • 打赏
  • 举报
回复
引用 8 楼 ckc 的回复:
代码和代码之间依赖越少越好,依赖多了,会把事情搞的太复杂,最后就牵一发而动全身,程序没办法修改了
是的,不过为了效率,必须还是要做出一些牺牲的。然后上面说的延迟处理的方法我觉得是最靠谱的,不过在C++代码中延迟处理感觉有点奇怪,而且这样其实要改的地方也不少了。
ckc 2018-08-28
  • 打赏
  • 举报
回复
代码和代码之间依赖越少越好,依赖多了,会把事情搞的太复杂,最后就牵一发而动全身,程序没办法修改了
哈利_蜘蛛侠 2018-08-27
  • 打赏
  • 举报
回复
引用 5 楼 ckc 的回复:
数组的话先复制一份应该管用吧 链表的话比较麻烦,处理的时候会改变在链表中的位置,这个太恶心了 如果处理不需要顺序的话可以设置一个属性标记是不是处理过了 搞完一轮再搞一轮直到全部数据都标记处理过了
其实不希望动那个遍历过程本身。我现在是打算这样来处理这个问题: 由于这个遍历经常发生,所以拷贝一份ID列表或者指针列表之类的方法不靠谱。我就从那些会改变数组元素顺序的函数ChangeOrder()(如果不是函数,就先抽象成一个函数)开刀。首先我可以判断当前是否在进行遍历。所以我就分开来处理: 1、如果当前没有在遍历数组,那么ChangeOrder()做的事情跟以前一样; 2、如果当前正在进行遍历,那么ChangeOrder()就往某个数据结构中做一个注册操作,表示自己马上要做本想做的事情,然后等到遍历结束的时候,就去遍历这个数据结构,真正去做本想要用ChangeOrder()做的事情。 由于数组的遍历经常发生,而数组元素顺序的变化是很少发生的,所以我觉得这个是非常合理的一种策略。
cjzzmdn 2018-08-27
  • 打赏
  • 举报
回复
DoSth() 会做什么呢

把已经DoSth()之后的对象的地址保存一下 DoSth()之前判断一下
ckc 2018-08-26
  • 打赏
  • 举报
回复
数组的话先复制一份应该管用吧
链表的话比较麻烦,处理的时候会改变在链表中的位置,这个太恶心了
如果处理不需要顺序的话可以设置一个属性标记是不是处理过了
搞完一轮再搞一轮直到全部数据都标记处理过了
赵4老师 2018-08-26
  • 打赏
  • 举报
回复
引用 3 楼 Contritio 的回复:
如果遍历不要求顺序的话,先生成一个对应的指针数组,然后利用这个指针数组来进行对应操作。

void **p = (void**)malloc(aObjectList.size() * sizeof(void*));
for(int i = 0; i < aObjectList.Size(); ++i)
{
p[i] = (void*)&aObjectList[i] ;
}
for(int i = 0; i < aObjectList.Size(); ++i)
{
p[i]->DoSth();
}
free(p );
p = NULL ;

__STATIC 2018-08-26
  • 打赏
  • 举报
回复
如果遍历不要求顺序的话,先生成一个对应的指针数组,然后利用这个指针数组来进行对应操作。

void **p = (void**)malloc(aObjectList.size() * sizeof(void*));
for(int i = 0; i < aObjectList.Size(); ++i)
{
p[i] = (void*)&aObjectList[i] ;
}
for(int i = 0; i < aObjectList.Size(); ++i)
{
p[i]->DoSth();
}
free(p );
p = NULL ;
望晓天 2018-08-26
  • 打赏
  • 举报
回复
没有太理解楼主要表达的想法 我觉得既然你要实现某个相应的成员函数,直接调用又会改变顺序不如加一个判断语句,理解不是很充分希望能对你有所帮助

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧