C ++ Найти и сохранить дубликаты в векторе - PullRequest
0 голосов
/ 03 мая 2018

У меня есть пользовательский вектор моего пользовательского типа вектора

Первый вектор заполняется элементами через stdin, затем я сортирую его и пытаюсь найти в нем дубликаты и сохранить их

Мне удалось найти все уникальные элементы, но мне нужно найти и получить вектор дубликатов. Мне нужна подсказка или простое решение для этой проблемы

вот мой код ниже:

Agressor.h

#ifndef Agressor_h
#define Agressor_h

#include <string>
#include <vector>

using namespace std;

class Agressor{
public:
    /*const char**/ string traderIdentifier;
    /*const char**/ string side;
    int quantity;
    int price;
    vector<Agressor> v;

    void display(){
        cout << traderIdentifier << " " << side << " " << quantity << " " << price << endl;
    }
    explicit Agressor(){

    }
    ~Agressor(){

    }
    friend ostream &operator<<(ostream& stream, const Agressor& item);
    const friend bool operator > (const Agressor &a1, const Agressor &a2);

   // const friend bool operator == (const Agressor &a1, const Agressor &a2);

    /* vector<Agressor>& operator[](int i ){
        return v[i];
    }*/


};


ostream &operator<<(ostream& stream, const Agressor& item) {
    string side = "";
    if(item.side == "B"){
        side = '+';
    }else{
        if(item.side == "S"){
            side = "-";
        }
    }

    stream << item.traderIdentifier << side << item.quantity << "@" << item.price << "\n";
    return stream;
}

const bool operator == (const Agressor &a1, const Agressor &a2){
    bool isEqual = false;
    if((a1.price*a1.quantity == a2.price*a2.quantity) && (a1.traderIdentifier == a2.traderIdentifier) && (a1.side == a2.side)){
        isEqual = true;
    }
    return(isEqual);
}


const bool operator > (const Agressor &a1, const Agressor &a2){
    bool isGreater = false;
    if(a1.price*a1.quantity > a2.price*a2.quantity){
        isGreater = true;
    }
    return(isGreater);
}



#endif /* Agressor_h */

main.cpp

#include <iostream>
#include "Agressor.h"
#include <sstream>
using namespace std;


vector<string> &split(const string &s, char delim, vector<string> &elems)
{
    stringstream ss(s);
    string item;
    while (getline(ss, item, delim))
    {
        elems.push_back(item);
    }
    return elems;
}

vector<string> split(const string &s, char delim)
{
    vector<string> elems;
    split(s, delim, elems);
    return elems;
}

bool equal_comp(const Agressor& a1, const Agressor& a2){
    if((a1.price*a1.quantity == a2.price*a2.quantity) && (a1.traderIdentifier == a2.traderIdentifier) && (a1.side == a2.side)){
        return true;
    }
    return false;
}

int main(int argc, const char * argv[]) {
    Agressor agr;
    while (true) {
            std::string sText;
            cout << "enter query:" << endl;
            std::getline(std::cin, sText);
        if(sText == "q"){
            cout << "Program terminated by user" << endl;
            break;
        }else{
            std::vector<std::string> sWords = split(sText, ' ');
            agr.traderIdentifier = sWords[0];
            agr.side = sWords[1];
            agr.quantity = stoi(sWords[2]);
            agr.price = stoi(sWords[3]);
            agr.v.push_back(agr);

            vector<Agressor>::iterator it;
            sort(agr.v.begin(), agr.v.end(), greater<Agressor>());
            //unique(agr.v.begin(), agr.v.end(), equal_comp);
            for (vector<Agressor>::const_iterator i = agr.v.begin(); i != agr.v.end(); ++i)
                cout << *i << ' ';

    }
    }
    cout << "here we go..." << endl;
    vector<Agressor>::iterator it;
    sort(agr.v.begin(), agr.v.end(), greater<Agressor>());
    //it = unique(agr.v.begin(),agr.v.end(), equal_comp);
    //agr.v.resize( distance(agr.v.begin(),it) );
    agr.v.erase(unique(agr.v.begin(),agr.v.end(), equal_comp), agr.v.end());

    copy(agr.v.begin(), agr.v.end(), ostream_iterator<Agressor>(cout, "\n"));



    return 0;
}

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

std::unique перезаписывает дублирующиеся значения более поздними, не дублирующимися значениями. Вы можете реализовать аналогичный алгоритм, который перемещает значения куда-то.

template<class ForwardIt, class OutputIt, class BinaryPredicate>
ForwardIt unique_retain(ForwardIt first, ForwardIt last, OutputIt d_first, BinaryPredicate p)
{
    if (first == last)
        return last;

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

(адаптировано из это возможная реализация из std::unique)

Вы бы тогда использовали это как

vector<Agressor> dups;
sort(agr.v.begin(), agr.v.end(), greater<Agressor>());
auto it = unique_retain(agr.v.begin(),agr.v.end(), std::back_inserter(dups), equal_comp);
agr.v.erase(it, agr.v.end());
0 голосов
/ 03 мая 2018

Вы можете использовать что-то вроде:

template <typename T>
std::vector<T> get_duplicates(const std::vector<T>& v)
{
     // expect sorted vector

     auto it = v.begin();
     auto end = v.end();
     std::vector<T> res;
     while (it != end) {
         it = std::adjacent_find(it, end);
         if (it != end) {
             ++it;
             res.push_back(*it);
         }
     }
     return res;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...