Составьте карту «регионов», в основном, std::map<coordinates/len, std::vector<point>>
.Добавьте каждую точку в ее регион, и каждый из 8 соседних регионов O(N*logN)
.Запустите алгоритм «nieve» для каждого из этих меньших списков (технически O(N^2)
, если нет максимальной плотности, тогда он становится O(N*density)
).Наконец: в вашем исходном списке выполните итерацию по каждому point
, и, если он был удален из любого из 8 мини-списков, в которые он был добавлен, удалите его из списка.O(n)
Без ограничения по плотности, это O(N^2)
, и медленно.Но это становится все быстрее и быстрее, чем больше разбросаны точки.Если точки в некоторой степени равномерно распределены на известной границе, вы можете переключиться на двумерный массив, что сделает это значительно более быстрым, а если есть постоянный предел плотности, то технически делает это алгоритмом O(N)
.
Таким образом, вы сортируете список двух переменных.Сетка / карта / 2dvector.
[EDIT] Вы упомянули, что у вас тоже были проблемы с методом "nieve", так что вот что:
template<class iterator, class criterion>
iterator RemoveCriterion(iterator begin, iterator end, criterion criter) {
iterator actend = end;
for(iterator L=begin; L != actend; ++L) {
iterator R(L);
for(++R; R != actend;) {
if (criter(*L, *R) {
iterator N(R);
std::rotate(R, ++N, actend);
--actend;
} else
++R;
}
}
return actend;
}
Это должно работать в связанных списках, векторы и аналогичные контейнеры, и работает в обратном порядке.К сожалению, это довольно медленно из-за отсутствия учета свойств связанных списков.Можно сделать намного более быстрые версии, которые работают только со связанными списками в определенном направлении.Обратите внимание, что возвращаемое значение важно, как и в других алгоритмах мутации.Он может изменять только содержимое контейнера, но не сам контейнер, поэтому вам придется стирать все элементы после возвращаемого значения после его завершения.