简体   繁体   English

在city.begin()处启动地图迭代器

[英]Starting a map iterator not at city.begin()

In short, when trying to iterate through a map, is it possible to start the iterator at an index/key that isn't *.begin()? 简而言之,当尝试遍历地图时,是否可以在不是* .begin()的索引/键处启动迭代器?

I have a map of cities with a class " City ". 我有一个带有“ City ”类的城市map (City has coordinates for the city, and in the following code, calc_dist(c1, c2) will calculate the distance between the coordinates). (城市具有城市坐标,在以下代码中,calc_dist(c1,c2)将计算坐标之间的距离)。 What I am trying to do is create a "2D Map" (ie map<string, map<string, double>> dist ) that can access the distance between the city by using dist[city1][city2] . 我想做的是创建一个“ 2D Map”(即map<string, map<string, double>> dist ),可以使用dist[city1][city2]访问城市之间的距离。

to compute the distances I basically create a nested iterator over the cities, and it works, but it's slow when using many cities. 为了计算距离,我基本上在城市上创建了一个嵌套的迭代器,它可以工作,但是在使用许多城市时速度很慢。 since the distance between cities are symmetric, i can cut the loops in half by storing the distance in the reverse of the map. 由于城市之间的距离是对称的,因此我可以通过将距离存储在地图的反面来将环切成两半。

what i was hoping to do was start the second iterator at the current city from the first iterator. 我希望做的是从第一个迭代器在当前城市启动第二个迭代器。 http://www.cplusplus.com/reference/map/map/ tells me that the order is preserved so I feel like I should be able to do this. http://www.cplusplus.com/reference/map/map/告诉我订单已保留,因此我认为我应该能够这样做。

Sample code: 样例代码:

// Function create_distance_chart(...)
map<string, map<string, double>> create_distance_chart(map<string, City> c){

    map<string, map<string, double>> dist;

    for (map<string, City>::iterator it = c.begin(); it != c.end(); ++it){

        for (map<string, City>::iterator it2 = c.begin(); it2 != c.end(); ++it2) { // here i can make improvements, i hope

            //calculate distance

            dist[c[it->first]][c[it2->first]] = calc_dist(c[it->first],c[it2->first])// store in map
            dist[c[it2->first]][c[it->first]] = calc_dist(c[it->first],c[it2->first])// store in map in the other direction.  
        }
    }
}

in the line 在行中

for (map<string, City>::iterator it2 = c.begin(); it2 != c.end(); ++it2) {

i tried to change c.begin to c[it->first] , c.at(it->first) , just it->first , and a dummy variable that pulls the index for it->first . 我试图将c.begin更改为c[it->first] c.begin c[it->first]c.at(it->first) ,只是it->first和一个为it->first拉索引- it->first的虚拟变量。

the only other method i'm considering is doing a reverse iterator for the second iterator and having a termination condition that might cause the second loop to end before it2 != c.end() (ie at the first iterator's city), but i'm not making headway in that domain right now. 我正在考虑的唯一其他方法是对第二个迭代器执行反向迭代器,并具有终止条件,该条件可能导致第二个循环在它之前it2 != c.end() (即在第一个迭代器所在的城市),但是我目前不在该领域取得进展。

Thanks in advance! 提前致谢!

First of all this statment: 首先这句话:

c[it->first]

is a slow and convoluted way to simply say: 是一种缓慢而复杂的方式来简单地说:

it->second

and as you use that 8 times in your loop there is no surprise it is slow indeed. 而且当您在循环中使用8次时,它确实很慢也就不足为奇了。

And for your loop, looks like you want to change second loop to: 对于您的循环,看起来您想将第二个循环更改为:

for (map<string, City>::iterator it2 = std::next(it); it2 != c.end(); ++it2)

Note: if you do not have intention to change values in the map it is cleaner to use std::map::const_iterator instead. 注意:如果您不想更改地图中的值,则使用std::map::const_iterator更为干净。

Note2: I assumed that calculating distance btw a city and itself is meaningless. 注意2:我假设计算城市与城市之间的距离是没有意义的。 If it is not the case in your geometry then remove std::next() in above code and just assign it to it2 in the second loop initialization. 如果不是在你的几何体的情况下再取出std::next()在上面的代码中,只是赋予itit2在第二循环中的初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM