2014-12-11 8 views
0

Я пытаюсь использовать std::set вместе с VectorXd из библиотеки Эйгеном:VectorXd и станд :: Набор: дублирующие элементы

typedef VectorXd Vec; 

bool(*fn_pt)(Vec,Vec) = vecCompare; 
set<Vec,bool(*)(Vec,Vec)> yx (fn_pt); 

Функция vecCompare IST определяется следующим образом:

bool vecCompare(Vec v, Vec w) { 
    int n = v.rows(); 

    for (int i = 0; i < n; ++i) { 
     if (v(i) < w(i)) { 
      return true; 
     } else if (v(i) > w(i)) { 
      return false; 
     } 
    } 

    return false; 
} 

Unfortunality , Я получаю дубликаты в yx. Есть идеи?

Edit1: Для простых примеров все отлично работает, например,

set<Vec,vecCompare> test; 
Vec t(3); 
t(0)=33; 
t(1)=44; 
t(2)=55; 

test.insert(t); 
test.insert(t); 

Я мой код я ввожу около 2000 векторов, и я получаю около 200 повторяющихся элементов.

Редактировать2: Векторы вычисляются по алгоритму. Я выводимый векторы в том порядке, в котором они вставлены в yx, пока два дублирующих элементов вставляются, в результате чего в следующем списке:

10068.4, 2355, 4794 
9787.28, 4582, 2532 
10188, 3218, 3111 
7696.03, 3506, 3540 
7933.94, 2864, 4844 
8321.96, 4432, 2804 
8502.21, 3732, 2928 
9976.05, 3859, 2681 
9623.74, 3397, 2967 
8815.94, 2987, 3556 
9082.79, 2693, 3954 
9976.81, 2574, 3991 
10002.5, 3443, 2915 
8264.29, 3392, 3290 
7169.08, 4594, 3622 
7073.8, 4756, 3771 
7005.82, 3749, 4985 
7833, 4000, 3150 
8096.63, 2876, 4193 
8107.36, 2892, 4143 
7459.51, 3246, 4489 
9061.37, 2480, 4617 
7718.64, 3001, 4820 
9069.39, 2471, 4861 
7744.1, 4449, 3155 
8320.67, 4120, 2850 
8875.47, 4655, 2596 
8858.44, 4321, 2627 
8616.2, 4085, 2759 
8114.57, 3602, 3176 
8114.57, 3602, 3176 

Затем я создал эти 30 векторов вручную и вставить их вручную в набор , Удивительно, все работает нормально. Я этого не понимаю.

Edit3: Я также заметил, что при работе следующее, что zz остается на 0, хотя yx содержит около 200 дубликатов.

int zz = 0; 
    for (auto y1: yx) { 
    int i = 0; 
    for (auto y2: yx) { 
     if (y1 == y2) { 
     i++; 
     } 

     if (i > 1) zz++; 
    } 
    } 
+0

Вы пробовали 'set yx;'? – timrau

+0

Не компилирует (g ++ 4.9): swsda.cc:66:19: ошибка: несоответствие типа/значения в аргументе 2 в списке параметров шаблона для шаблона <класс _Key, класс _Compare, класс _Alloc> класс std :: set ' set yx; ^ swsda.cc:66:19: ошибка: ожидается тип, получил 'vecCompare' ... –

ответ

0

Вы могли бы попытаться объявить vecCompare в качестве функционального объекта, а не функции.

typedef VectorXd Vec; 
struct vecCompare { 
    bool operator()(const Vec &v, const Vec &w) const 
    { 
     int n = v.rows(); 

     for (int i = 0; i < n; ++i) { 
      if (v(i) < w(i)) { 
       return true; 
      } else if (v(i) > w(i)) { 
       return false; 
      } 
     } 

     return false; 
    } 
}; 

set<Vec, vecCompare> yx; 

Однако до тех пор, как VectorXd магазины double в качестве элементов, вы должны проявлять особую осторожность с плавающей запятой точности вопрос. Два числа с плавающей запятой, которые , похоже, равны, равны не могут быть действительно равными.

+0

Нет, я все еще получаю повторяющиеся элементы. Я просто использую функцию 'insert' для вставки элементов. –

+0

@Storchi Не могли бы вы показать некоторые примеры векторов, дублированных при таком функциональном объекте сравнения? – timrau

+0

См. Мое редактирование исходного вопроса. –

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