清除向量中的对象重复项会产生无限循环

时间:2018-11-11 21:55:34

标签: c++ vector

我有一个向量:

vector<MiniPair> miniPairVector;

MiniPair对象内部有2个属性,1是整数docNumber,另一个是字符串word

我正在尝试清除此向量中的重复项,这意味着如果docNumber和word存在于向量中的另一个对象中,请删除重复项

这是我尝试过的方法,但是会产生无限循环:

for (int i = 0; i < miniPairVector.size(); i++) {

    for (int k = i + 1; k < miniPairVector.size(); k++) {

        if (miniPairVector[i].getDocNumber() == miniPairVector[k].getDocNumber() && miniPairVector[i].getWord() == miniPairVector[k].getWord()) {
            cout << "i am erasing" << endl;
            miniPairVector.erase(miniPairVector.begin() + k);

        }

    }

}

这是minipair类:

#pragma once
// classes example
#ifndef MINIPAIR_H
#define MINIPAIR_H
#include <iostream>
using namespace std;

class MiniPair {
    friend bool operator<(MiniPair const &a, MiniPair const &b) {

        return a.docNumber < b.docNumber || a.docNumber == b.docNumber && a.word < b.word;
    }
    friend bool operator==(MiniPair const &a, MiniPair const &b) {

        return a.docNumber == b.docNumber && a.word == b.word;
    }
private:
    string word;
    int docNumber;

public:
    MiniPair();
    MiniPair(string word, int docNumber);
    string getWord();
    int getDocNumber();

};
#endif

2 个答案:

答案 0 :(得分:3)

我的推测是您正在上课。

首先,尽管由于类施加的约束,这可能与您要解决的问题不相关,但是这是实现此问题的一种较差的方法。正确实施后,比较次数将类似于miniPairVector.size() * miniPairVector.size()。这是很多比较,远远超出了您的实际需求。

如果我试图在非玩具(或非指派)程序中执行此操作,则应使用标准库的<algorithm>部分。我会先使用::std::sort,然后再使用::std::unique

这是我使用这两个方法的方法:

#include <algorithm>

void remove_dupes(::std::vector<MiniPair> &minipair_vec)
{
    ::std::sort(minipair_vec.begin(), minipair_vec.end(),
                [](MiniPair const &a, MiniPair const &b) -> bool {
                    return (a.getDocNumber() < b.getDocNumber())
                           || ((a.getDocNumber() == b.getDocNumber())
                               && (a.getWord() < b.getWord())));
               }); // End lambda and sort.
     auto newend = ::std::unique(minipair_vec.begin(), minipair_vec.end(),
                                [](MiniPair const &a, MiniPair const &b) -> bool {
                                   return a.getDocNumber() == b.getDocNumber()
                                          && a.getWord() == b.getWord();
                                }); // End lambda and unique.
     minipair_vec.resize(newend - minipair_vec.begin());
}

我已经对其进行了测试,因此它应该可以正常工作。

一般的教训是,如果您发现自己在循环播放,请仔细阅读以下问题:

  • 我是否正在索引线性数据结构?如果是这样,为什么我使用索引而不是迭代器?
  • 是否已经有一种算法可以满足我的需要?或者可以轻松组合两种算法来满足我的需要?

我提供的代码应在与minipair_vec.size() * ::std::log2(minipair_vec.size())成比例的时间内运行。您编写的代码将在与minipair_vec.size() * minipair_vec.size()成比例的时间内运行(一旦运行该代码),对于大列表来说,这要花更长的时间。

答案 1 :(得分:2)

C ++ 98解决方案:

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

struct MiniPair {
    int docNumber;
    std::string word;
    friend bool operator<(MiniPair const &a, MiniPair const &b) {
        return a.docNumber < b.docNumber || a.docNumber == b.docNumber && a.word < b.word;
    }
    friend bool operator==(MiniPair const &a, MiniPair const &b) {
        return a.docNumber == b.docNumber && a.word == b.word;
    }
};

int main() {
    std::vector<MiniPair> miniPairVector;
    // fill miniPairVector with data
    std::sort(miniPairVector.begin(), miniPairVector.end());
    miniPairVector.erase(std::unique(miniPairVector.begin(), miniPairVector.end()), miniPairVector.end());
}