如何使用更通用的数据结构
How can I use a more generic data structure?
>我正在尝试创建一个文本解析器,该解析器将允许有限的用户定义的替换规则。
也就是说,我正在从DOS ASCII文件中读取代码,其中排序很重要,并且必须保持行号。 有了这个输入,我想应用用户定义的替换规则(用这个字符串交换那个字符串,如果我们看到这个字符串后跟那个字符串,执行这个翻译,等等(。
输出也是一个格式化的 DOS ASCII 文件。
大多数规则都是直接替换 tit 进行 tat 类型替换,但是,在某些情况下,我想定义一个规则,例如如果 A 后面跟着 B 在将来的任何时候,请应用此规则。
为此,我使用了这样的结构树:
struct node {
list<string> common; // the text which is not affected by conditions
string condition; // matching this string selects the left, otherwise the right
node *lptr, *rptr; // pointers to the child nodes, if needed
};
每当我遇到这样的规则时,我都可以在省略和应用规则的情况下维护输出,延迟决定使用哪个规则,直到明确解决为止。
这有点浪费内存,但似乎是避免两次传递输入数据的最佳方法(输入数据的大小未知,但可能小于 1 meg(。
当然,可能存在这样的情况,即在一个或两个子节点中触发这种类型的不同规则,因此这就是树结构的原因。
没有限制孩子必须在父母之前决定,可能是父母只能在孩子的一个分支上决定。 遇到EOF会决定任何犹豫不决的孩子朝着错误的方向发展。
所以很明显,我在倒带和折叠节点时必须小心。
对于这个普遍问题,有更简单的解决方案吗? 有没有办法以比我的树呈现的更有效的方式使用标准库容器?
你可能想看看NFA和DFA,即非确定性有限状态自动和确定性有限状态自动。这两种方法是编写解析器的最常见且通常非常有效的方法。
实际上不需要将数据存储在节点中,否则它会被传递并浪费内存。更好的方法是,分配一个变量(例如 int state = 0(来跟踪当前的解析状态。根据当前状态和输入,您的算法将更改状态。状态总是向前移动,但你可以告诉你的算法在某个条件不匹配时返回到以前的某个状态(称为"回溯"(。
例如,如果"ab"和"ac">是两个有效的输入,那么在解析"ac"时,算法可能是这样的:
char is 'a' ==> go to state.checkB
char is not 'b' ==> go back to state.checkA
checkB was already done ==> go to state.checkC
char is 'c' ==> DoSomething();
需要大量的文章和图表才能完全解释所有内容,希望这会让您知道在哪里进一步查看。
假设"文本解析器"的意思是你试图压缩相同含义的单词和短语,以简化对命令的反应。
在这种情况下,根据旧文本冒险程序,使用规则查找表的简单左右解析器将在这里工作。
除非我误解了您的问题域,否则您的解决方案似乎过度设计。
听起来你应该尝试正则表达式。以下是有关选择库的讨论链接:C++正则表达式库选择。Boost是一种流行的。
另外,您是否考虑过使用另一种语言来解决问题?Python有一个很好的有用库基础,包括一个用于正则表达式(import re(的库。如果它在您的驾驶室中,您可能会发现它比C++解决方案更容易。
最后,考虑对输入文件使用"已定义"的文本格式,而不是自定义格式。XML 是一个不错的选择。在 XML 树中嵌套规则可能更容易。C++,你可以使用Expat XML解析器(Python将是xml.etree.ElementTree(。
- 如何使用set实现无序数据结构?
- 我可以使用哪种数据结构来处理这种方式
- 为什么我们使用在C++中返回数据结构的函数?
- 使用带有链表的堆栈数据结构将中缀转换为后缀
- 使用完数据结构后清空数据结构是一个好习惯吗?
- 在结构中使用 switch 引用结构中的数据C++
- 使用链表数据结构打印多项式
- 我应该为地图使用哪种数据结构?(C++)
- 使用 trie 数据结构链接不同类型的信息
- 从输入中删除重复项,而不使用任何数据结构
- C++ 数据结构队列:使用 for 循环查找队列中最大的元素
- 将 OpenGL VBO 与自定义类/数据结构一起使用
- 在现有数据结构上使用BGL算法需要什么(边和顶点作为矢量<对象*>)?
- 在命令数据结构中使用联合
- C++中的无锁数据结构=只使用原子和内存排序
- 将 STL 队列与自定义数据结构结合使用
- 同时在 epoll 数据结构中使用 void *ptr 和 int fd
- 如何在结构数据结构中使用 map stl 并初始化映射,然后引用它
- 哪些数据结构正在使用多少内存
- 为什么我们不能在算法和数据结构中使用参考呢