Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 核对两份清单_C++_C_Algorithm_Iterator - Fatal编程技术网

C++ 核对两份清单

C++ 核对两份清单,c++,c,algorithm,iterator,C++,C,Algorithm,Iterator,因此,我有两个不同的列表,需要协调不同的格式和结构。本质上,集合B需要匹配集合A中的内容,但我希望保留集合B中现有项目的状态,而不是用集合A中的内容覆盖它们 作为参考,列表实际上并不意味着列表。“列表”有两种不同的形式,从直线阵列到地图。它们都使用标准迭代器访问元素 我通常的处理方式是这样的 for item in listA if listB contains item mark item in list B as visited else add item to

因此,我有两个不同的列表,需要协调不同的格式和结构。本质上,集合B需要匹配集合A中的内容,但我希望保留集合B中现有项目的状态,而不是用集合A中的内容覆盖它们

作为参考,列表实际上并不意味着列表。“列表”有两种不同的形式,从直线阵列到地图。它们都使用标准迭代器访问元素

我通常的处理方式是这样的

for item in listA
  if listB contains item
     mark item in list B as visited
  else 
     add item to list b

 for item in listB
   if visited is true
      continue
   else
       add item to removeList

 for item in removeList
    remove item from list B
这是我能想到的唯一可行的方法。我不喜欢我要做多少次迭代,让三个for循环背靠背感觉是不对的。但是,由于我使用的是迭代器,所以在检查列表时无法从列表中删除任何内容,而必须将它们添加到第三个删除列表中

在可能的答案中,请记住,对我来说,速度和内存占用比编写代码的容易程度更重要

我的问题可以归结为,有没有更好的方法可以做到这一点

我是C++/C FWIW,尽管我认为任何解决方案都可能是语言无关的


谢谢

这里有另一种可能更有效的方法:

removeList = listB

for item in listA
  if listB contains item
    remove item from removeList
  else
    add item to listB

for item in removeList
  remove item from listB
因此,它不是从无到有地构建removeList,而是从所有内容开始,然后从中删除项目

您还可以通过使用removeList存储索引而不是实际项来提高效率。只要在初始循环中将项目添加到listB的末尾,并且以相反的顺序删除项目,索引就应该仍然有效

事实上,如果用要保留的项的布尔数组替换removeList,则更简单。所以算法变成这样:

initialise all itemsToKeep to false
savedListLength = length of listB

for item in listA
  offset = find item in listB
  if found
    mark itemsToKeep[offset] as true
  else
    add item to listB

for offset from savedListLength-1 down to 0
  if itemsToKeep[offset] is false
    remove the offset from listB
这避免了最初需要将任何内容复制到removeList中。而itemstokep数组的开销肯定不会比您在算法中跟踪可视项所用的任何东西更糟糕


在某种程度上,最合适的算法可能取决于列表的形式(即向量或链表等),但我确实认为我的方法可能更有效。

希望“包含”是一个常量或至少在时间op中。任何原因都不能立即删除列表B中的项,而不是标记为(不)访问并再次迭代以杀死它?只要稍加努力,我相信迭代器就能正确处理这个问题?这是我最关心的问题。我对STL迭代器的理解是,在对底层数据结构进行迭代时,不能对其进行触摸(在删除或插入方面)。我能想到的任何“修复”都比遍历移除列表要昂贵——一般情况下,移除列表会非常小。我相信,在STL容器上调用“移除”时,它会为您提供一个新的迭代器,您可以使用它来继续您的横向操作。试试看事情是否会加速。这比我想象的要好吗?将列表b复制到removelist将导致列表b的迭代,您必须迭代A和removelist,所以总的来说,您仍然看到相同的迭代次数。@MotimeMediator这是一个公平点,但就代码行而言,它更整洁,这很重要。而且它不需要标记任何我认为也是加号的东西。@MotimeMediator还更新了答案,以显示如何修改我的算法,从而完全摆脱removeList。