文本文件
[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结构中。
我需要一个使用三个整数值的函数;ID(例如10000),X(例如-500)和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);
}
};
看到它住在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;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句