C ++:将元素从unordered_set复制到向量

时间:2014-09-04 01:16:24

标签: c++ vector unordered-set

背景:我正在为旅行商问题实施最近邻算法。我需要计算巡回旅行的距离以及跟踪所访问点的顺序。我已经定义了一个带有实例变量xy的点类以及一个用于计算两点之间距离的函数calcDist。我首先将所有点存储在名为std::unordered_set的{​​{1}}中,创建一个名为points的空std::vector来存储游览路径,并将起点指定为{{ 1}},并将这些传递给我的path函数:

startPoint

问题是,一旦程序退出外部for循环,nearestNeighbor()中的所有点都会以某种方式被覆盖。看看我的意思,这是输出:

void nearestNeighbor(unordered_set<Point, PointHasher> points, vector<Point> &path, Point startPoint) {
  // Declare variables
  unordered_set<Point, PointHasher>::iterator it;
  Point currentLocation, possibleNeighbor, nearestNeighbor;
  double totalDist = 0;
  int pointsCount = path.capacity() - 1;

  // Set the starting location
  it = points.find(startPoint);
  currentLocation = *it;
  path[0] = currentLocation;
  points.erase(currentLocation);
  cout << "Start location: " << path[0].x << ", " << path[0].y << endl;

  // Create the path
  for (int i = 1; points.size() > 0; i++) {
    double minDist = -1;
    // Find the current location's nearest neighbor
    for (it = points.begin(); it != points.end(); it++) {
      possibleNeighbor = *it;
      int currentDist = currentLocation.calcDist(possibleNeighbor);
      if (minDist == -1 || currentDist < minDist) {
        minDist = currentDist;
        nearestNeighbor = possibleNeighbor;
      }
    }
    // Record nearest neighbor data and prepare for the next iteration
    currentLocation = nearestNeighbor;
    path[i] = currentLocation;
    points.erase(currentLocation);
    totalDist += minDist;
    cout << "Nearest neighbor: " << path[i].x << ", " << path[i].y << endl;
  }
  // Return to the starting location
  path[pointsCount] = startPoint;
  cout << "End location: " << startPoint.x << ", " << startPoint.y << endl;
  cout << "Path:" << endl;
  for (int i = 0; i < path.size(); i++) {
    cout << path[0].x << ", " << path[0].y << endl;
  }
  cout << "Total distance: " << totalDist << endl;
}

我认为这要么是向量元素的指针/地址的问题,要么是具有范围的东西,因为问题在退出for循环后发生。我甚至尝试在每次迭代后打印path以查看它何时被更改,但它在整个循环中是正确的,并且只在结尾处输出更改。有什么想法吗?我很难过。如果你已经做到这一点,非常感谢你的时间。

3 个答案:

答案 0 :(得分:2)

您始终输出路径[0] man

的坐标
for (int i = 0; i < path.size(); i++) {
    cout << path[0].x << ", " << path[0].y << endl;
}

答案 1 :(得分:1)

你有

for (int i = 0; i < path.size(); i++) {
    cout << path[0].x << ", " << path[0].y << endl;
  }

这不会遍历i。将您的0更改为i,您可能会看到更有帮助的内容:

for (int i = 0; i < path.size(); i++) {
    cout << path[i].x << ", " << path[i].y << endl;
}

修改:将path[i] = currentLocation;更改为path.push_back(currentLocation); - 这会自动增加path向量的大小以适应新元素。

void nearestNeighbor(
    unordered_set<Point, PointHasher> points,
    vector<Point> &path,
    Point startPoint,
    double &totalDist) // note the new variable passed here
{
  // Declare variables
  unordered_set<Point, PointHasher>::iterator it;
  Point currentLocation, possibleNeighbor, nearestNeighbor;
  // double totalDist = 0; Remove this line
  // int pointsCount = path.capacity() - 1; And this

  // Set the starting location
  it = points.find(startPoint);
  currentLocation = *it;
  path.push_back(currentLocation); // Changed this line
  points.erase(currentLocation);
  cout << "Start location: " << path[0].x << ", " << path[0].y << endl;

  // Create the path
  for (int i = 1; points.size() > 0; i++) {
    double minDist = -1;
    // Find the current location's nearest neighbor
    for (it = points.begin(); it != points.end(); it++) {
      possibleNeighbor = *it;
      int currentDist = currentLocation.calcDist(possibleNeighbor);
      if (minDist == -1 || currentDist < minDist) {
        minDist = currentDist;
        nearestNeighbor = possibleNeighbor;
      }
    }
    // Record nearest neighbor data and prepare for the next iteration
    currentLocation = nearestNeighbor;
    path.push_back(currentLocation); // And this line
    points.erase(currentLocation);
    totalDist += minDist;
    cout << "Nearest neighbor: " << path[i].x << ", " << path[i].y << endl;
  }
  // Return to the starting location
  path.push_back(startPoint); // And here also!
  cout << "End location: " << startPoint.x << ", " << startPoint.y << endl; // This I didn't change, 
// but perhaps you should make it reflect the last point in the vector, 
// not the start point which is supposed to be the last point in the vector
  cout << "Path:" << endl;
  for (int i = 0; i < path.size(); i++) {
    cout << path[i].x << ", " << path[i].y << endl;
  }
  cout << "Total distance: " << totalDist << endl;
}

答案 2 :(得分:0)

我看不到任何增加path向量大小的地方。

我怀疑你为第二个参数传递了一个空的std :: vector,并且只要你点击path[0]=currentLocation; ...未定义的行为。

另外,我并不认为capacity()会按照您的想法行事。

那,并且正如其他人所指出的那样,你并没有正确地输出数组的内容,但这是一个小问题。这里的主要问题是这个程序可能会乱写并破坏堆。