1

我有一个由三列 x、y 和 z 组成的数据文件(这些是数字)。我想做以下事情:

  1. 比较数据中的每个 (x, y) 集。
  2. 如果两个集合相等,比如 (x1, y1) = (x2, y2),
  3. 然后,比较 z1 和 z2。根据比较,我将编写一个条件,并且我想覆盖其中一个集合,以便它采用通过我所做的某些条件的那个集合的值。

数据包含数千个点,所以我不确定如何有效地进行比较,以及如何覆盖或省略不通过该条件的点。

所以有人可以提出一些建议,或者举一个小例子来说明我只有两个点(x1,y1,z1)和(x2,y2,z2)的情况。

4

2 回答 2

2

由于您想将所有点与所有其他点进行比较,您可以执行如下算法。假设这样的数据结构:

struct Data {
    double x_, y_, z_;
    bool skip;
    const std::pair<double, double> & xy () const {
        return std::pair<double, double>(x, y);
    }
};

std::vector<Data> file;
typedef std::multimap<std::pair<double, double>, unsigned> PointMap;
PointMap xyline;

然后,当您读入文件时,您会搜索xyline以查看当前点是否已经存在。如果是这样,请相应地更新当前点和file向量(因为您知道所有匹配点的行号,您可以修改所有匹配项或仅修改最新的匹配项,您的选择)。然后插入与当前行关联的当前点,然后迭代到文件中的下一行。

处理完文件后,写出file. 然后,如果您愿意,可以使用输出替换现有文件。

void update (PointMap::iterator first, PointMap::iterator last, Data &d) {
    //... revisit all matching points and decide which to keep
}

Data d;
std::ifstream ifile;
std::ofstream ofile;
ifile.open("input.dat");
while (ifile >> d.x_ >> d.y_ >> d.z_) {
    PointMap::iterator i = xyline.find(d.xy());
    if (i != xyline.end()) {
        update(i, xyline.upper_bound(d.xy(), d);
    }
    xyline.insert(i, std::pair<d.xy(), file.size());
    file.push_back(d);
}

ofile.open("output.dat");
for (size_t i = 0; i < file.size(); ++i) {
    d = file[i];
    if (!d.skip)
        ofile << d.x_ << " " << d.y_ << " " << d.z_ << "\n";
}
于 2012-07-17T13:56:19.377 回答
0
typedef std::map<float, float> Leafs;
typedef std::map<float, Leafs> Node;

Node root;

以这种方式填充树:假设您要添加 (a,b,c)

Leafs l;
l[ b ] = c;
root[ a ] = l;

然后当您添加新值时,使用find(检查 std::map::find 方法描述)方法来检查值是否存在。这应该是这个“问题”的足够快的解决方案

于 2012-07-17T13:25:30.523 回答