关于c ++:数据转换/转换是否有良好的模式/习语?

Are there good Patterns/Idioms for Data Translation/Transformation?

我对这个问题的一般性标题感到抱歉,但我希望我能少用一般性的语言表达出来。:-}

我想编写一个软件(在这种情况下,使用C++),它将输入令牌流转换成输出令牌流。只有五个输入令牌(我们称它们为0、1、2、3、4),每个令牌可以有几个不同的属性(例如,可能有一个4.x属性或0.foo)。还有一些输出标记,大约10个,让我们调用它们(out0..out9),每个标记也有一些属性。

现在,我们正在研究从输入令牌到可能的输出令牌的序列映射,如下所示:

1
2
3
01 -> Out0
34 -> Out1
0101 -> Out3

…因此不同的输入令牌序列映射到单个输出令牌。

在我的场景中,输入令牌集是固定的,但输出令牌集不是固定的——我们可能决定引入新的"产品"。我的问题是:

有人知道在这种情况下是否有好的模式和/或习惯用法有帮助吗?

现在我有了一组"压缩器"对象,每个对象都可以使用输入令牌并最终生成输出令牌。问题是有些输入令牌冲突,在上面的例子中考虑"out0"和"out3"。输入"0101"应产生out3而不是out0。但是,输入'0104应该产生0,然后将0和4留在队列中。

我想知道是否有来自数据压缩的模式或者其他可能有益的领域。

这种将低级令牌的输入减少到高级令牌并处理可能的冲突的工作在解析器编写器中很常见,不是吗?有没有有用的模式?

更新:

更多信息:

  • 在我的具体案例中,输入令牌是C结构,输出令牌是C++对象。我对令牌的输入流没有任何控制,但是我可以对它们进行排队,然后在有利的情况下修改队列。

  • 我通过尝试先匹配out3,然后再匹配out0来解决冲突(比如out3(0101)和out0(01)),但有点难看。可能的产品在一个列表中,我只是尝试将它们一个接一个地应用到输入流中。

  • 可能的产品列表可以由用户扩展,所以我不能生成一个巨大的DAG,然后有一个状态机来实现它来处理每个可能的转换。当然,这意味着用户可以添加冲突,但事实就是这样。


  • 您可以定义一个图,其中每个节点包含一个输入令牌和一个相关的输出。每个节点的链接描述可能的下一个令牌。因此,图中的路径描述了一个可能的转换规则。

    要转换数据,请从与第一个输入标记对应的节点开始,并尝试在尽可能长的路径上导航图形,将下一个输入标记与链接到当前节点的节点匹配。当没有链接的节点与下一个输入节点匹配时,将与当前节点关联的输出作为结果。


    几年前,我会立刻说,看看比森http://www.gnu.org/software/bison/或yacc,但我已经有一段时间没有做过类似的事情了,所以不知道还有没有更好的。

    对于您正在做的事情,使用它们可能有点过头了,但使用的习惯用法可能会很有用。


    在设计数据压缩算法时,需要注意一个代码的开头不能被误认为是另一个较短的代码。这是汉明码的基础。另一种选择是使用一个分隔符来分隔标记,就像摩尔斯电码(在字符之间使用一个短的停顿)。