Используя повышение:: случайный как RNG для станд.:: random_shuffle

Прежде всего вам необходимо определить, по каким критериям объекты должны быть уникальными. Например, есть ли идентифицирующее свойство? В этом случае должны работать следующие параметры.

Наиболее эффективный способ, вероятно, состоит в том, чтобы сделать подход с помощью набора работ. Для этого вам нужно будет превратить ваши объекты в объекты данных, что означает, что они идентифицируются на равенство по значениям свойств. Для этого вы должны переопределить оператор равенства и методы хэш-кода. Однако это меняет поведение ваших объектов при каждой операции равенства. Так что вам придется судить, подходит ли это. Смотрите эту статью .

Другой вариант - просто отфильтровать вручную, используя карту:

class MyObj {
  String val;

  MyObj(this.val);
}

TestListFiltering(){
  List l = [
    MyObj("a"),
    MyObj("a"),  
    MyObj("b"),
  ];
  // filter list l for duplicate values of MyObj.val property
  Map mp = {};
  for (var item in l) {
    mp[item.val] = item;
  }
  var filteredList = mp.values.toList();
}

11
задан Piotr Dobrogost 11 July 2009 в 19:27
поделиться

3 ответа

В C++ 03, Вы не можете инстанцировать шаблона на основе функционально-локального типа. При перемещении класса рэнда из функции он должен хорошо работать (правовая оговорка: не протестированный, могли быть другие зловещие ошибки).

Это требование было ослаблено в C++ 0x, но я не знаю, было ли изменение реализовано в C++ GCC 0x режим уже, и я буду высоко удивлен найти это существующим в любом другом компиляторе.

11
ответ дан 3 December 2019 в 02:53
поделиться

В комментариях Robert Gould попросил рабочую версию для потомства:

#include <algorithm>
#include <functional>
#include <vector>
#include <boost/random.hpp>

struct bar : std::unary_function<unsigned, unsigned> {
    boost::mt19937 &_state;
    unsigned operator()(unsigned i) {
        boost::uniform_int<> rng(0, i - 1);
        return rng(_state);
    }
    bar(boost::mt19937 &state) : _state(state) {}
};

void foo(std::vector<unsigned> &vec, boost::mt19937 &state)
{
    bar rand(state);
    std::random_shuffle(vec.begin(), vec.end(), rand);
}
13
ответ дан 3 December 2019 в 02:53
поделиться

Я использую tr1 вместо boost :: random здесь, но это не имеет большого значения.

Следующий вариант немного сложен, но он работает.

#include <algorithm>
#include <tr1/random>


std::tr1::mt19937 engine;
std::tr1::uniform_int<> unigen;
std::tr1::variate_generator<std::tr1::mt19937, 
                            std::tr1::uniform_int<> >gen(engine, unigen);
std::random_shuffle(vec.begin(), vec.end(), gen);
5
ответ дан 3 December 2019 в 02:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: