我正在尝试推广数据结构(在C ++中),这样我就可以将输入数据转换为更有用的形式,而且我尝试的每种不同方法都会遇到明显的问题,使其无法使用。我在这里的研究有助于指出这些问题,但它并没有帮助我找到问题的解决方案。
为了简洁起见,这是实际问题。每个数据点都是一对 - 一个字符串和一个未知数据类型(很可能是字符串,双精度或整数)。第一个字符串将是字符X.Y(1).Z
,但该格式未标准化(例如,某些格式将显示为X.Y.Z(A)(1)
或X(1).Y
)。 (parens中的值有向量索引作为整数或映射为不同的“子变量”,如[A,B,C]。)
我正在尝试将其重组为一种“动态”的数据结构树,以便我可以轻松访问它(即不参考原始的,可能很长的字符串)并且通常(我不知道字符串在编译时,因此不能简单地为它准备)。
到目前为止,我已经决定使用unordered_map<string, (some type T here)>
作为“树”的根,而pair<(some type T), boost::variant>
类型似乎是处理底部“叶子”的合适方式。 / p>
我的问题是:有什么方法可以将结构从顶部的unordered_map
到中间级别一直概括到底部的pair
,这样就可以了对于任何字符串 - 无论是X.Y.Z
还是更复杂的情况?或者我是否需要在更高级别编写我的泛化(例如,指向具有多个可能派生化身的通用数据对象的指针)?或者我完全走错了轨道?
不幸的是,由于其专有性质,我无法显示任何实际数据,但X.Y(1).Z
格式应该提供它的要点。
答案 0 :(得分:0)
您的问题未明确,但让我想起了Boost PropertyTree - 它能够以各种格式读取通用值树结构输入。
如果您可以稍微改变一下格式,您可以快速获得结果。一个例子说千言万语:
输入
; an int
X.Y(1).Z 42
; a float
X.Y.Z(A)(1) 3.1415926
; a string
X(1).Y "Hello world"
subtree {
X(2).Y Bye
}
程序
<强> Live On Coliru 强>
#include <iostream>
#include <boost/property_tree/info_parser.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/json_parser.hpp>
int main()
{
using tree = boost::property_tree::ptree;
tree pt;
read_info("input.txt", pt);
std::cout << "The float is " << pt.get<double>(tree::path_type("X.Y.Z(A)(1)", '|')) << "\n";
write_ini(std::cout << "\nINI:\n", pt);
write_info(std::cout << "\nINFO:\n", pt);
write_json(std::cout << "\nJSON:\n", pt);
std::cout << "Greeting: " << pt.get(tree::path_type("subtree|X(2).Y", '|'), "No greeting") << "\n";
std::cout << "Final words: " << pt.get(tree::path_type("subtree|missing|final.words", '|'), "No final words") << "\n";
}
输出
The float is 3.14159
INI:
X.Y(1).Z=42
X.Y.Z(A)(1)=3.1415926
X(1).Y=Hello world
[subtree]
X(2).Y=Bye
INFO:
X.Y(1).Z 42
X.Y.Z(A)(1) 3.1415926
X(1).Y "Hello world"
subtree
{
X(2).Y Bye
}
JSON:
{
"X.Y(1).Z": "42",
"X.Y.Z(A)(1)": "3.1415926",
"X(1).Y": "Hello world",
"subtree": {
"X(2).Y": "Bye"
}
}
Greeting: Bye
Final words: No final words
注意:
get<>
的类型即可
'.'
是Boost属性树路径中的默认路径分隔符,这有点不幸。因此,查询的方式有点笨拙(tree::path_type("X(1).Y", '|')
而不是"X(1).Y"
,例如。)