c ++算法删除重复项 - 两个值

时间:2015-02-13 08:34:16

标签: c++ algorithm

编辑注意:这不是代码审查,而是重新提出问题。

关于算法实施的讨论:https://codereview.stackexchange.com/questions/80412/c-algorithm-remove-duplicates-both-values

我的特例: 家庭项目,播客自动下载器。

整体算法是:

  1. 下载可用播客列表
  2. 哈希播客
  3. 从sqlite db
  4. 加载元数据+下载的播客的哈希值
  5. 算法这个问题是关于 - 扔掉所有已下载的。
  6. 下载新播客
  7. 将元数据保存到sqlite db
  8. 请注意,此算法仅用于删除2个重复项,如果超过2个重复项,请查看整体算法。

    问题:这个算法4有一个名称还是一个等价算法?

    问题:有不同于我下面的示例代码的方法

    作为讨论的基础代码 要求:c ++ 11编译器,例如gcc 4.9 注意:复制粘贴就绪代码。

    #include <algorithm> #include <vector> #include <iostream> #include <iterator> #include <string> template <typename ForwardItr> ForwardItr doubleEraser(ForwardItr first, ForwardItr last) { auto itr = first; typename std::iterator_traits<ForwardItr>::value_type firstMatch = *first; bool hasFirstMatch(false); while(itr != last) { auto next = std::next(itr); if(next != last && *itr == *next) { if(!hasFirstMatch) { hasFirstMatch = true; firstMatch = *itr; } else { if(*itr == firstMatch) // again at first match { return itr; } } std::rotate(itr, std::next(itr, 2), last); // throw matched elements to the end of container } else ++itr; } return last; } template <typename T> void print(T& c) { for(auto & element : c) std::cout << element << " "; std::cout << "\n"; } template <class T> void process(std::vector<T>& t) { std::string formating(" \t"); std::cout << "input: " << formating; print(t); std::sort(t.begin(), t.end()); std::cout << "sorted:" << formating; print(t); auto itr_begin = doubleEraser(t.begin(), t.end()); std::cout << "dEraser:" << formating; print(t); t.erase(itr_begin, t.end()); std::cout << "output:" << formating; print(t); } int main() { std::vector<int> vec {1,2,3,4,5,6,7,8,9,3,5,6,7,2}; std::vector<char> vec2 {'A', 'C', 'D', 'D', 'G', 'A' }; std::vector<std::string> vec3 {"Hello", "World", "that", "be", "that", "Hello"}; process(vec); process(vec2); process(vec3); }

2 个答案:

答案 0 :(得分:0)

需要更多空间复杂性的简单方法。以相反的顺序映射唯一值及其索引,然后仅按索引排序即可形成一个辅助向量。 string可以执行类似的操作,但需要特定的比较功能。

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>

bool cmp(std::pair<int, int>& a,
         std::pair<int, int> & b)
{
    return  a.second < b.second;
}

void removedups(std::vector<int>& out)
{
    std::map<int, int> vecmap;
    std::vector<std::pair<int, int>> sorted;

    for(int i=out.size()-1; i >= 0; i--)
        vecmap[out[i]] = i;

    for(auto it : vecmap)
        sorted.push_back(it);

    std::sort(sorted.begin(), sorted.end(), cmp);

    for(auto it : sorted)
        std::cout << "[" << it.first << "]";
}

int main()
{
    std::vector<int> v= {1,1, 2, 2, 7, 2, 2, 7, 7, 2, 3, 8, 4, 5, 3, 2, 3, 2, 6, 2, 3, 2, 9, 10, 1, 2, 2, 1};
    removedups(v);
    for(auto p : v)
        std::cout << p<< "  ";

    return 0;
}

答案 1 :(得分:-1)

我认为你所描述的(或者你想要的)是std::unique。它会删除范围内的所有连续重复项(因此不仅仅是两个重复项,如算法)。要工作,std :: unique要求对输入范围进行排序,并按如下方式实现:

template<class ForwardIt>
ForwardIt unique(ForwardIt first, ForwardIt last)
{
    if (first == last)
        return last;

    ForwardIt result = first;
    while (++first != last) {
        if (!(*result == *first)) {
            *(++result) = std::move(*first);
        }
    }
    return ++result;
}