2013-04-21 6 views
3

У меня есть вектор, который содержит идентификатор элемента вместе с координатами x и Y. Что я хочу сделать, это проверить, имеют ли они одинаковые координаты x и y? - и если они удаляют один из них (на основе другого поля).Найти повторяющиеся элементы в векторе

Однако я нашел в Google «уникальную» функцию, потому что все идентификаторы уникальны, это не сработает? Верный?

Я думал о прохождении каждого из элементов в сопоставлении вектора, используя вложенный цикл, есть ли лучший способ?

Благодаря J

+1

не 'set' лучший способ делать то, что вы хотите сделать, я в первую очередь используйте 'set'. – user2244984

+4

'std :: unique' - это путь. Посмотрите на перегрузки функции, вы можете указать, как сравнивать элементы. –

+0

Каждое из полей в векторе является классом. Я не думаю, что система будет работать. – KingJohnno

ответ

5

Я только что пошел и написал несколько примеров. Я надеюсь, что это помогает.

#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <iterator> 


using namespace std; 


// Sample coordinate class 
class P { 
public: 
    int x; 
    int y; 
    P() : x(0), y(0) {} 
    P(int i, int j) : x(i), y(j) {} 
}; 


// Just for printing out 
std::ostream& operator<<(ostream& o, const P& p) { 
    cout << p.x << " " << p.y << endl; 
    return o; 
} 

// Tells us if one P is less than the other 
bool less_comp(const P& p1, const P& p2) { 

    if(p1.x > p2.x) 
     return false; 
    if(p1.x < p2.x) 
     return true; 

    // x's are equal if we reach here. 
    if(p1.y > p2.y) 
     return false; 
    if(p1.y < p2.y) 
     return true; 

    // both coordinates equal if we reach here. 
    return false; 
} 


// Self explanatory 
bool equal_comp(const P& p1, const P& p2) { 

    if(p1.x == p2.x && p1.y == p2.y) 
     return true; 

    return false; 
} 

int main() 
{ 

    vector<P> v; 
    v.push_back(P(1,2)); 
    v.push_back(P(1,3)); 
    v.push_back(P(1,2)); 
    v.push_back(P(1,4)); 

    // Sort the vector. Need for std::unique to work. 
    std::sort(v.begin(), v.end(), less_comp); 

    // Collect all the unique values to the front. 
    std::vector<P>::iterator it; 
    it = std::unique(v.begin(), v.end(), equal_comp); 
    // Resize the vector. Some elements might have been pushed to the end. 
    v.resize(std::distance(v.begin(),it)); 

    // Print out. 
    std::copy(v.begin(), v.end(), ostream_iterator<P>(cout, "\n")); 

} 

+0

Да, хороший! Это должно говорить хорошо. –

2

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

Используйте vector.sort с пользовательской функцией сравнения, которая сравнивает x- и y-координаты. Затем итерации вектор один раз, сравнивая каждый элемент с предыдущим.

Если вы не хотите, чтобы изменить порядок вектора, вы можете также перебирать вектор от начала до конца, и сравнить каждый элемент для всех элементов с более высоким индексом:

for (int i = 0; i < vector.size(); i++) { 
    Position current = vector.at(i); 
    for (int j = i+1; j < vector.size(); j++) { 
     if current.isEqualPosition(vector.at(j)) { 
      // found a duplicate 
     } 
    } 
} 

К way: В зависимости от ваших точных требований лучшим способом обработки объектов в 2d-пространстве может быть пользовательская структура данных, например, two-dimensional tree.

+0

Hm, это имеет сложность O (N^2) –

+0

@ hr_117 И это также решение Named. Считаете ли вы, что std :: sort и std :: unique - магия? – Philipp

+0

Нет, я не думаю, что это было бы волшебством. ;-) Но сортировка должна быть O (N * logN) и уникальной, надеюсь, только O (N). –

Смежные вопросы