c++ - 我可以读取输入数据并创建通用的 C++ 数据结构吗?

标签 c++ string dictionary boost input

我试图概括一个数据结构(在 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
}

程序

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" 例如)

关于c++ - 我可以读取输入数据并创建通用的 C++ 数据结构吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35616649/

相关文章:

php - 从字符串中返回所有匹配的 css

javascript - JQuery 从字符串中的标签中提取值

java - 检查字符串是否包含另一个整个字符串

c# - 关于 Dictionary<T,T> 的问题

python - 什么更有效地迭代列表并调用函数或将列表传递给函数

dictionary - 如何在Python 3中实现UserDict.DictMixin的功能?

c++ - 为什么 “k” 语句中的 “m =++i ||++j &&++k” 没有递增?

c++ - 如何将数组中的值存储到 OpenCV 中的 Mat

javascript - 如何使用 NPAPI 创建一个新的 JS 对象?

c++ - 最小化单应矩阵中的误差