擦除有序向量c ++中的重复值

时间:2015-06-28 16:19:35

标签: c++ loops vector stl iterator

我正在尝试删除排序字符串向量中的所有重复项。但是,我一直在犯错,我无法弄清楚原因。我相信它与矢量大小调整有关,同时也在循环中使用。这是代码:

auto it = name.begin() + 1;
int count = 1; 

while(it != name.end())
{
    if (*it == *(it - 1))
    {
        count++;
        it++;
    }
    else if (*it != *(it - 1) && count > 1) {
        it = name.erase(it - count , it - 1);
        cout << *it << " occurs " << count << " times." << endl; 
        count == 1;
    }
}

代码检查前一个元素是否重复,然后将其删除。重要的是要知道元素发生的次数,因为我必须这样做。知道如何解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

擦除重复元素后,当前元素没有前面的元素。

else if (*it != *(it - 1) && count > 1) {
    it = name.erase(it - count , it - 1);
    cout << *it << " occurs " << count << " times." << endl; 
    count == 1;
}

因此,在下一次迭代中,表达式*it == *(it - 1)*it != *(it - 1)无效。

此外,它可以以name.end()之前的所有元素彼此相等的方式发生。在这种情况下,什么都不会被删除。

您可以使用标头std::unique中声明的标准算法<algorithm>。例如

#include <algorithm>
#include <vector>
#include <string>

//..

name.erase( std::unique( name.begin(), name.end() ), name.end() );

答案 1 :(得分:0)

  

知道如何解决这个问题吗?

有趣的努力。我相信我已经确定了两个有趣的可能性。

你的循环开始于向量&#39; name&#39;的开头。这可以。现在你需要找到一种机制来延迟这些重复元素的vector :: erase()。 &#34;矢量::擦除()&#34;在擦除时或之后使任何迭代器无效。这可能就是为什么矢量支持后面的操作...我们可以利用这一点。

在互联网上找到:迭代器有效性

  • 指向的迭代器,指针和引用  位置(或第一个)及以后的位置无效,

  • 所有迭代器,指针和位置前元素的引用 (或第一个)保证以继续引用相同的元素 他们是在电话会议前提到的。

因此,通过首先在名称向量的后面工作,我们可以最小化指针失效。

我做了,并建议你尝试,是添加第二个向量来保存duplicate-element-iterators。我用以下typedef&#39; s标记了我的副本

typedef std::vector<std::string>  Names; 
typedef Names::iterator           NamesIT; 
// --- 
typedef std::vector<NamesIT>      NamesItVec; 


vector<NamesItVec>  dups.

当您识别出所有重复项,并将名称迭代器推送到dup中后,您可以旋转重复,此时擦除重复的名称元素。

请注意,当从向量的背面擦除时,erase()更容易在内存中重新排列。 (早期分拣工作的有效&#39;二次使用。)

看起来像这样:

std::cout << "\nremoving dups from vector name: back to front" << std::endl;

while (dups.size()) // as long as it has a iterator in it
{
   auto dupIT = dups.back(); // reference closest element to strVec.end()

   std::cout << "==> " << (*dupIT) << std::endl;  // debug info

   (void)names.erase(it);      // erase the single element

   dups.pop_back();             // remove the last element from dups
}

希望这不是太多的帮助。祝你好运。