Во-первых, давайте сделаем простой случай, который расскажет о вашей проблеме:
struct Point { int bathyDepth; }; // this is all, what you need to show
int main()
{
// some points
Point a{ 1 }, b{ 100 }, c{ 1000 }, d{ 2000 }, e{ 3000 }, f{ 4000 }, g{ 4501 }, h{ 400 }, i{ 1600 }, j{ 2200 }, k{ 700 };
// one map element
std::map<std::string, std::vector<Point> > seamap
{ {"Nat", std::vector<Point>{a, b, c, d, e, f, g, h, i, j, k}} };
//Partition basins by depth
for (auto it2= seamap.begin(); it2!= seamap.end(); ++it2)
{
int i = 500; // some range
auto itp = std::partition(it2->second.begin(), it2->second.end(), [&i](const auto &a) {return a.bathyDepth < i; });
}
return 0;
}
Я просто не уверен, как хранить itp
.
Для хранения нужно знать только его тип.
что равно decltype(it2->second)::iterator
, так как std::partition
возвращает тип контейнера итератора.
Так как key_type вашей карты равен std::vector<Point>
, он равен std::vector<Point>::iterator
Вы можете проверить это программно:
if (std::is_same<decltype(it2->second)::iterator, decltype(itp)>::value)
std::cout << "Same type";
Это означает, что вы можете хранить itp
в
using itpType = std::vector<Point>::iterator;
std::vector<itpType> itpVec;
// or any other containers, with itpType
Конечной целью является вычисление расстояния между точкой данных и всеми
другие точки данных в конкретном окне глубины (например, от 1500 до
2500м).
Если это так, вам нужно просто отсортировать значения карты (std::vector<Point>
) по bathyDepth
и выполнить итерацию по ней, чтобы найти необходимый диапазон. Когда вы используете std::partition
, внутри этого цикла
for (int i = 500; i<=4500; i+=500 )
конечный эффект / результат такой же, как сортировка сразу, но вы делаете это шаг за шагом. Также обратите внимание, что для получения правильного результата с помощью std::partition
вам нужно отсортировать std::vector<Point>
.
Например, см. пример кода здесь , который напечатает диапазон, как вы упомянули.
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
struct Point
{
int bathyDepth;
// provide a operator< for std::sort()
bool operator<(const Point &rhs)const { return this->bathyDepth < rhs.bathyDepth; }
};
// overloaded << operator for printing #bathyDepth
std::ostream& operator<<(std::ostream &out, const Point &point) { return out << point.bathyDepth; }
//function for printing/ acceing the range
void printRange(const std::vector<Point>& vec, const int rangeStart, const int rangeEnd)
{
for (const Point& element : vec)
{
if (rangeStart <= element.bathyDepth && element.bathyDepth < rangeEnd) std::cout << element << " ";
else if (element.bathyDepth > rangeEnd) break; // no need for further checking
}
std::cout << "\n";
}
int main()
{
Point a{ 1 }, b{ 100 }, c{ 1000 }, d{ 2000 }, e{ 3000 }, f{ 4000 }, g{ 4501 }, h{ 400 }, i{ 1600 }, j{ 2200 }, k{ 700 };
std::map<std::string, std::vector<Point> > seamap
{ {"Nat", std::vector<Point>{a, b, c, d, e, f, g, h, i, j, k}} };
for (auto it2 = seamap.begin(); it2 != seamap.end(); ++it2)
{
// sort it
std::sort(it2->second.begin(), it2->second.end());
//Partition basins by depth
for (int i = 0; i < 4500; i += 500) printRange(it2->second, i, i + 500);
}
return 0;
}
Выход:
1 100 400
700
1000
1600
2000 2200
// no elements in this range
3000
// no elements in this range
4000