gpt4 book ai didi

c++ - 这些方法中哪些是可能的/更有效的

转载 作者:搜寻专家 更新时间:2023-10-31 00:30:30 24 4
gpt4 key购买 nike

我有一个这样格式的文本文件

ignore contents for about 8 lines
...
x y z
- [7.6515, -10.8271, -28.5806, 123.8]
- [7.6515, -10.8271, -28.5806, 125.0]
- [7.6515, -10.8271, -28.5806, 125.9]
- [7.6515, -10.8271, -28.5806, 126.8]
- [7.6515, -10.8271, -28.5806, 127.9]
- [7.6515, -10.8271, -28.5806, 128.9]
- [7.6515, -10.8271, -28.5806, 130.0]
- [7.6515, -10.8271, -28.5806, 130.9]
- [7.6515, -10.8271, -28.5806, 131.8]

有没有办法从可能的 35000 多条线中获取 x,y 点,这些线看起来像上面的那些一次每一行?如果是这样,这是最好的方法吗?

或者,

在每一行上使用 getline 方法,然后使用 boost::regex 解析该行是否更好?

我需要获取 x,y 点并将它们填充到 float 组中。

我一直在使用 boost::regex 来满足我的需要,但这需要我一次获取每一行。我不知道它的效率如何,所以我想知道是否有更好的解决方案。如果没有,我可以继续我一直在做的事情。

解决方案必须用 c++ 完成。

最佳答案

这是使用 Boost Spirit X3 和映射文件进行的拍摄。

struct Point { double x, y, z; };

template <typename Container>
bool parse(std::string const& fname, Container& into) {
boost::iostreams::mapped_file mm(fname);

using namespace boost::spirit::x3;

return phrase_parse(mm.begin(), mm.end(),
seek[ eps >> 'x' >> 'y' >> 'z' >> eol ] >> // skip contents for about 8 lines
('-' >> ('[' >> double_ >> ',' >> double_ >> ',' >> double_ >> omit[',' >> double_] >> ']')) % eol, // parse points
blank, into);
}

Spirit 是一个解析器生成器,因此它会根据表达式(例如 'x' >> 'y' >> 'z' >> eol 以匹配标题行)为您生成解析代码。

与正则表达式不同,Spirit 知道如何处理和转换值,因此您可以使用 with 例如vector<Point> :

int main()
{
std::vector<Point> v;

if (parse("input.txt", v)) {
std::cout << "Parsed " << v.size() << " elements\n";
for (Point& p : v) {
std::cout << "{" << p.x << ';' << p.y << ';' << p.z << "}\n";
}
} else {
std::cout << "Parse failed\n";
}
}

完整演示

此处程序使用嵌入问题的示例数据解析自身:

Live On Coliru

#include <iostream>
#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/iostreams/device/mapped_file.hpp>

struct Point { double x, y, z; };

BOOST_FUSION_ADAPT_STRUCT(Point,x,y,z)

template <typename Container>
bool parse(std::string const& fname, Container& into) {
boost::iostreams::mapped_file mm(fname);

using namespace boost::spirit::x3;

return phrase_parse(mm.begin(), mm.end(),
seek[ eps >> 'x' >> 'y' >> 'z' >> eol ] >> // skip contents for about 8 lines
('-' >> ('[' >> double_ >> ',' >> double_ >> ',' >> double_ >> omit[',' >> double_] >> ']')) % eol, // parse points
blank, into);
}

int main()
{
std::vector<Point> v;

if (parse("main.cpp", v)) {
std::cout << "Parsed " << v.size() << " elements\n";
for (Point& p : v) {
std::cout << "{" << p.x << ';' << p.y << ';' << p.z << "}\n";
}
} else {
std::cout << "Parse failed\n";
}
}

#if DATA
ignore contents for about 8 lines
...
x y z
- [7.6515, -10.8271, -28.5806, 123.8]
- [7.6515, -10.8271, -28.5806, 125.0]
- [7.6515, -10.8271, -28.5806, 125.9]
- [7.6515, -10.8271, -28.5806, 126.8]
- [7.6515, -10.8271, -28.5806, 127.9]
- [7.6515, -10.8271, -28.5806, 128.9]
- [7.6515, -10.8271, -28.5806, 130.0]
- [7.6515, -10.8271, -28.5806, 130.9]
- [7.6515, -10.8271, -28.5806, 131.8]
#endif

打印

Parsed 9 elements
{7.6515;-10.8271;-28.5806}
{7.6515;-10.8271;-28.5806}
{7.6515;-10.8271;-28.5806}
{7.6515;-10.8271;-28.5806}
{7.6515;-10.8271;-28.5806}
{7.6515;-10.8271;-28.5806}
{7.6515;-10.8271;-28.5806}
{7.6515;-10.8271;-28.5806}
{7.6515;-10.8271;-28.5806}

关于c++ - 这些方法中哪些是可能的/更有效的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36706242/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com