2011-12-23 2 views
2

Я хочу отсортировать vector на основе координат x и y. Следующее - это то, что я сделал, но то, что я хочу, - это когда я сортирую на основе x, я получаю должное, но когда я иду на сортировку на основе y, я не хочу, чтобы мой заказ x изменился.сортировка по координатам x и y

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

struct item_t { 
    int x; 
    int y; 
    item_t(int h, int w) : x(h), y(w) {} 
    friend std::ostream& operator<<(std::ostream& os, const item_t& gt) { 
     os << "(" << gt.x << "," << gt.y << ")"; 
     return os; 
    } 
}; 
typedef std::vector<item_t> item_list_t; 
typedef item_list_t::iterator item_list_itr_t; 

struct compare_x { 
    bool operator()(const item_t& left, const item_t& rigx) const { 
     return left.x < rigx.x; 
    } 
}; 
struct compare_y { 
    bool operator()(const item_t& left, const item_t& rigx) const { 
     return left.y < rigx.y; 
    } 
}; 

int main (int argc, char **argv) { 
    item_list_t items; 

    items.push_back(item_t(15, 176)); 
    items.push_back(item_t(65, 97)); 
    items.push_back(item_t(72, 43)); 
    items.push_back(item_t(102, 6)); 
    items.push_back(item_t(191, 189)); 
    items.push_back(item_t(90, 163)); 
    items.push_back(item_t(44, 168)); 
    items.push_back(item_t(39, 47)); 
    items.push_back(item_t(123, 37)); 

    std::sort(items.begin(), items.end(), compare_x()); 
    std::copy(items.begin(),items.end(), std::ostream_iterator<item_t>(std::cout," ")); 
    std::cout << std::endl; 

    std::sort(items.begin(), items.end(), compare_y()); 
    std::copy(items.begin(),items.end(), std::ostream_iterator<item_t>(std::cout," ")); 

    std::cout << std::endl; 

} 

То, что я хочу, задает множество пунктов заказов в порядке возрастания. то есть x и y оба возрастают.

+0

Можете ли вы привести пример вывода, который вы ожидаете? Это не очень ясно из вопроса. – Naveen

+0

Во-первых, вам нужно решить, что вы ожидаете, когда 'left.x rigx.y'. В таком случае, какой порядок они должны быть? – Skyler

ответ

5

Вы должны делать то за один проход:

struct compare_xy { 
    bool operator()(const item_t& left, const item_t& right) const { 
     return (left.x == right.x ? left.y < right.y : left.x < right.x); 
    } 
}; 
+0

Если это то, что он ищет (вместо 'std :: stable_sort'). В этом случае, однако, чтобы уважать порядок в его описании и примере, вы должны сравнить 'y's first, а не' x's. –

+0

То, что я поставил, соответствует тому, что я понимаю в вопросе - сначала сортируйте по X, а для сопоставления Xs, сортируйте по Y. – Mat

+0

Довольно сложно определить, что он хочет от вопроса. Я интерпретировал его как сортировку сначала по X, затем сортировку по Y, но не нарушаю порядок, когда Y равны. На самом деле то, что он, казалось, просил меня, было для стабильного вида. Но я признаю, что его вопрос можно было бы интерпретировать по-разному. –

4

Вы должны создать только один компаратор и только один вызов std::sort:

struct compare_xy { 
    bool operator()(const item_t& left, const item_t& right) const { 
     return (left.x < right.x) || ((left.x == right.x) && (left.y < right.y)); 
    } 
}; 
1

Это не совсем ясно для меня, что вы спрашивать. Если ваша цель состоит в том, чтобы сортировать по y, с x определения порядка, когда y «s равны, то один вызов для сортировки с помощью функции сравнения:

struct OrderYThenX 
{ 
    bool operator()(item_t const& lhs, item_t const& rhs) const 
    { 
     return lhs.y < rhs.y 
      || (!(rhs.y < lhs.y) && lhs.x < rhs.x); 
    } 
}; 

Это приведет к items имеющих одинаковую как он, наконец, имеет в ваш код.

Если, как кажется более вероятным из частей вашего описания и вашего Например, вы хотите, порядок между объектами с равными y с быть неизменным при сортировке по y, независимо от того, как значения были упорядочены по до x, вы должны использовать std::stable_sort. Просто напишите , что он может быть медленнее, чем std::sort.

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