检索结构中最接近的X和Y的功能?

Function to retrieve closest X & Y in structure?

本文关键字:功能 最接近 检索 结构      更新时间:2023-10-16

文本文件

[0]
total=0
[10000]
total=3
-593 427 683
-976 703 701
-974 307 688
[20000]
total=0
[30000]
total=1
197 -83 153
[30001]
total=1
77 49 244
[40000]
total=0
头文件

using namespace std;
struct LRopeSearch
{
    bool Special;
    int Counter;
    string PN;
    POINT XY;
};
struct LRopeData
{
    int X;
    int Y1;
    int Y2;
};
struct LRData
{
    int LRID;
    vector <LRopeData> Ropes;
};
typedef pair <int, LRData> LRPair;
extern map <int, LRData> LRMap;
void CreateRopeStructure();

使用我的CreateRopeStructure()函数,我将所有的文本文件信息放入LRopeData结构中。

我需要一个使用三个整数值的函数;a ID(例如10000),a X(例如-500),&a Y(例如400)并使用所有三个整数值,将根据ID,最近的X, Y1, &Y2值。

我有结构LRopeSearch,可以在这样做,但我需要的帮助超出这实际使用结构在一个函数中检索所述值。

谢谢。

啊。我花了一段时间来"想象"输入数据应该是什么意思。在你最后的评论之后,我现在明白了输入是由ID标识的几组(空)绳索。

绳子是有限的,垂直的线段,由(X, Y1)-(X, Y2)给出。


我已经简化了数据结构,因为在LRData中使用LRID是多余的:

typedef int                    LRID;
typedef std::vector<LRopeData> LRData;
typedef std::map<LRID, LRData> LRMap;

现在假设您已经实现了数据读取(CreateRopeStructure),您可以编写一个蛮力搜索:

LRMap CreateRopeStructure();
#include <algorithm>
#include <iostream>
int main()
{
    LRMap data = CreateRopeStructure();
    // ex. from OP
    int const ID = 10000;
    int const  X =  -500;
    int const  Y =   400;
    // select rope data by ID:
    auto& ropes = data[ID];
    if (ropes.empty())
    {
        std::cout << "infinite" << std::endl;
    } else
    {
        // get the distance to each rope
        std::vector<double> distances(ropes.size());
        std::transform(
                ropes.begin(), ropes.end(), 
                distances.begin(),
                [=](LRopeData const& rope) { return rope.distanceToPoint(X, Y); });
            // for c++03:
            // std::tr1::bind(&LRopeData::distanceToPoint, std::tr1::placeholders::_1, X, Y));
        // print the shortest distance
        std::cout << *std::min_element(distances.begin(), distances.end()) << std::endl;
    }
}

当然,最有趣的部分是:LRopeData::distanceToPoint:

struct LRopeData {
    int X;
    int Y1;
    int Y2;
    double distanceToPoint(double px, double py) const
    {
        int y1(Y1), y2(Y2);
        // normalize segment endpoints (y1, y2)
        if (y1>y2) std::swap(y1, y2);
        double dx = (px - X);
        double dy = 0;
        if (py<y1)   dy = (py - y1);
        if (py > y2) dy = (py - y2);
        return sqrt(dx * dx + dy * dy);
    }
};

参见Live On Coliru,它打印:

96.8401
OP 中查询的

完整代码清单

包括我对解析输入的看法:

#include <vector>
#include <map>
#include <cmath>
//#include <tr1/functional> // bind (for c++03)
struct LRopeData {
    int X;
    int Y1;
    int Y2;
    double distanceToPoint(double px, double py) const
    {
        int y1(Y1), y2(Y2);
        // normalize segment endpoints (y1, y2)
        if (y1>y2) std::swap(y1, y2);
        double dx = (px - X);
        double dy = 0;
        if (py<y1)   dy = (py - y1);
        if (py > y2) dy = (py - y2);
        return sqrt(dx * dx + dy * dy);
    }
};
typedef int                    LRID;
typedef std::vector<LRopeData> LRData;
typedef std::map<LRID, LRData> LRMap;
typedef std::pair<LRID, LRData> LRPair;
LRMap CreateRopeStructure();
#include <algorithm>
#include <iostream>
int main()
{
    LRMap data = CreateRopeStructure();
    // ex. from OP
    int const ID = 10000;
    int const  X =  -500;
    int const  Y =   400;
    // select rope data by ID:
    auto& ropes = data[ID];
    if (ropes.empty())
    {
        std::cout << "infinite" << std::endl;
    } else
    {
        // get the distance to each rope
        std::vector<double> distances(ropes.size());
        std::transform(
                ropes.begin(), ropes.end(), 
                distances.begin(),
                [=](LRopeData const& rope) { return rope.distanceToPoint(X, Y); });
            // for c++03:
            // std::bind(std::mem_fn(&LRopeData::distanceToPoint), std::placeholders::_1, X, Y));
        // print the shortest distance
        std::cout << *std::min_element(distances.begin(), distances.end()) << std::endl;
    }
}
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <fstream>
#include <cassert>
BOOST_FUSION_ADAPT_STRUCT(LRopeData, (int,X)(int,Y1)(int,Y2))
LRMap CreateRopeStructure()
{
    // input
    std::ifstream ifs("input.txt");
    ifs >> std::noskipws;
    typedef boost::spirit::istream_iterator It;
    It f(ifs), l;
    // grammar
    using namespace boost::spirit::qi;
    rule<It, LRPair(), blank_type, locals<int> > lrmap;
    lrmap %= '[' >> int_ >> ']' >> +eol
          >> "total" >> '=' >> omit [ int_ [ _a = _1 ] ] >> +eol
          >> repeat(_a) [ int_ >> int_ >> int_ >> +eol ]
          ;
    // parse
    LRMap data;
    assert(phrase_parse(f, l, +lrmap, blank, data));
    if (f!=l)
        std::cout << "Remaining unparsed: '" << std::string(f,l) << "'n";
    // done
    return data;
}