我试图概括一个数据结构(在 C++ 中),以便我可以将输入数据转换为更有用的形式,而且似乎我尝试的每种不同方法都会遇到明显的问题,使其无法使用。我在这里的研究帮助指出了这些问题,但并没有帮助我找到解决问题的方法。
为简洁起见,下面是实际问题。每个数据点成对出现——一个字符串和一个未知数据类型(很可能是字符串、 double 或整数)。第一个字符串将是字符 X.Y(1).Z
, 但该格式未标准化(例如,有些格式看起来像 X.Y.Z(A)(1)
或 X(1).Y
)。 (括号中的值有 vector 索引作为整数或映射作为不同的“子变量”,如 [A,B,C]。)
我正在尝试将它重组为一种“动态”的数据结构树,以便我可以轻松地访问它(即不引用原始的、可能很长的字符串)和一般的(我不知道字符串,因此不能简单地为它做准备)。
到目前为止,我已经决定使用 unordered_map<string, (some type T here)>
对于“树”的根和 pair<(some type T), boost::variant>
type 似乎是处理底部“叶子”的合适方法。
我的问题是:有什么方法可以概括 unordered_map
的结构吗?在顶部通过中间层向下到 pair
s 在底部,这样这将适用于任何字符串 - 无论是 X.Y.Z
还是上面更复杂的情况?或者我是否需要在更高级别编写泛化(例如,指向具有多个可能的派生化身的通用数据对象的指针)?还是我完全走错了路?
不幸的是,由于其专有性质,我无法显示任何实际数据,但是 X.Y(1).Z
格式应体现其要点。
最佳答案
您的问题未明确说明,但让我想起了 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
}
程序
#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"
例如)
关于c++ - 我可以读取输入数据并创建通用的 C++ 数据结构吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35616649/