[英]Accessing a partitioned vector within a map
我有一個具有以下結構的輸入文件
#Latitude Longitude Depth [m] Bathy depth [m] CaCO3 [%] ...
-78 -177 0 693 1
-78 -173 0 573 2
.
.
我創建了一個地圖,該地圖具有一個基於string
( 海洋盆地的名稱)的鍵和一個包含數據向量的值。 現在,我需要按bathyDepth
對向量進行bathyDepth
。 確切地說,我想對向量進行分區,以便可以在所有數據行之間進行深度為0
到500m
, 500m
到1500m
, 1000m
到2000m
的分區。
我已存儲的數據到地圖的結構,但我不能確定如何存儲和訪問該分區,這樣我可以再cout
處於特定深度的數據點。
我的嘗試:
//Define each basin spatially
//North Atlantic
double NAtlat1 = 0, NAtlong1 = -70, NAtlat2 = 75, NAtlong2 = -15;
//South Atlantic and the rest...
double SPLIT = 0;
struct Point
{
//structure Sample code/label--Lat--Long--SedimentDepth[m]--BathymetricDepth[m]--CaCO3[%]--CO3freefraction (SiO2 carb free)[%]--biogenic silica (bSiO2)[%]--Quartz[%]--CO3 ion[umol/l]--CO3critical[umol/l]--Delta CO3 ion[umol/kg]--Ref/source
string dummy;
double latitude, longitude, rockDepth, bathyDepth, CaCO3, fCaCO3, bSilica, Quartz, CO3i, CO3c, DCO3;
string dummy2;
//Use Overload>> operator
friend istream& operator>>(istream& inputFile, Point& p);
};
//MAIN FUNCTION
std::map<std::string, std::vector<Point> > seamap;
seamap.insert( std::pair<std::string, std::vector<Point> > ("Nat", vector<Point>{}) );
seamap.insert( std::pair<std::string, std::vector<Point> > ("Sat", vector<Point>{}) );
//Repeat insert() for all other basins
Point p;
while (inputFile >> p && !inputFile.eof() )
{
//Check if Southern Ocean
if (p.latitude > Slat2)
{
//Check if Atlantic, Pacific, Indian...
if (p.longitude >= NAtlong1 && p.longitude < SAtlong2 && p.latitude > SPLIT)
{
seamap["Nat"].push_back(p);
} // Repeat for different basins
}
else
{
seamap["South"].push_back(p);
}
}
//Partition basins by depth
for ( std::map<std::string, std::vector<Point> >::iterator it2 = seamap.begin(); it2 != seamap.end(); it2++ )
{
for (int i = 500; i<=4500; i+=500 )
{
auto itp = std::partition( it2->second.begin(), it2->second.end(), [&i](const auto &a) {return a.bathyDepth < i;} );
}
}
注意: a
是Point
類型。 如果我嘗試將itp
存儲到諸如矢量的結構中, itp
出現以下錯誤:
error: no matching function for call to ‘std::vector<Point>::push_back(__gnu_cxx::__normal_iterator<Point*, std::vector<Point> >&)’
我只是不確定如何存儲itp
。 最終目標是計算特定深度窗口(例如1500m
至2500m
)內一個數據點與所有其他數據點之間的距離。 對於這個新手的任何幫助,將不勝感激。
std :: partition在分區元素組之間的分隔點處返回迭代器,該元素是第二組元素中的第一個元素。 如果要將其存儲在另一個vector
,則向量類型應為
std::vector<std::vector<Point>::iterator>
您使用它的方式是,在隨后的分區調用中,您不想對整個向量進行分區,而只對一部分包含較大的元素進行分區(因為向量中的早期元素現在是較低的元素,因此您無需不需要將它們包含在以后的分區調用中,因為它們應該位於它們的位置,並且partition
描述中沒有任何內容表明它們不會被移動。 因此, i
循環的后續迭代中的第一個元素應該是在上一個循環期間返回的itp
迭代器。
首先,讓我們做一個簡單的案例來說明您的問題:
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至2500m)內一個數據點與所有其他數據點之間的距離。
如果是這樣,您只需要根據bathyDepth
對地圖的值( 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.