当前位置: 首页 > 知识库问答 >
问题:

如何动态分配循环数据?

罗学真
2023-03-14

为了便于示例,让我们定义一个玩具自动机类型:

data Automaton =
  Auto
    { success ::
      Automaton
    , failure ::
      Automaton
    }

这种结构被设计成通过循环,我们可以将每个Automaton想象成一个具有成功和失败转换到其他状态的状态。因此有限自动机必须递归定义。例如,这里是最简单的自动机:

sink =
  Auto sink sink

它由1个总是过渡到自身的状态组成。如果我们愿意,我们可以制造更复杂的自动机:

-- Transitions to a sink once it encounters a failure
otto1 =
  Auto otto1 sink

-- Mutually recursive automata
otto2 =
  Auto otto2 otto3

otto3 =
  Auto otto3 otto2

这些不错。但是接受用户输入并构建一个自动机可能会很好。例如,也许可以从过渡矩阵中构建一个。这里有一个天真的实现:

fromTransition :: [(Int, Int)] -> Automaton
fromTransition tMatrix =
  go 0
  where
    go n =
      let
        (succ, fail) =
          tMatrix !! n
      in
        Auto (go succ) (go fail)

然而,当我们尝试这样做时,开始出现问题。我们前面的例子是O(1)以遵循转换。然而,由于禁用缓存,因此每次进行转换时都必须对列表进行索引,因此由此产生的自动机是O(n)。此外,输入列表必须保存在内存中,只要该自动机处于活动状态。这基本上比使用转移矩阵作为自动机更糟糕。

我真正想要的是动态构建的自动机,其方法与之前显示的静态构建的自动机一样高性能。我想要一些方法来分析输入,构建一个自动机,然后释放输入。

在一种带有变异的语言中,这很容易做到,因为我们可以一点一点地创建结构,留下漏洞供以后更正。

我也不想把IO拖进去,因为一旦引入,它就无法被包含。

有没有一种像我所希望的那样动态分配循环结构的好方法?

共有1个答案

卫梓
2023-03-14

懒惰来拯救。我们可以递归地定义所有子自动机的列表,使得它们的转换索引到相同的列表中:

fromTransition :: [(Int, Int)] -> Automaton
fromTransition m = a !! 0 where
  a = map (\(succ,fail) -> Auto (a !! succ) (a !! fail)) m

在所有转换至少被遍历一次之后,生成的自动机将是您期望的循环图,而不需要任何对矩阵的引用(特别是,转换将在恒定时间内进行)。

我们也可以使用seq提前强制自动机。

fromTransition :: [(Int, Int)] -> Automaton
fromTransition m = forced `seq` (a !! 0) where
  a = map (\(succ,fail) -> Auto (a !! succ) (a !! fail)) m
  forced = foldr (\(Auto x y) r -> x `seq` y `seq` r) () a
 类似资料:
  • 问题内容: 因此,我正在尝试做某事,不确定是否可能。我有以下代码: 我想做的是为{0..5}的每个实例分配一个唯一的变量,因此为每个变量名指定group1 group2 group3 group4。然后,我将./user0更改为./user$i并根据我的序列创建动态变量列表。这可能吗?尝试执行此操作时出现以下错误,但我不确定bash不喜欢自己实际执行了什么操作。 test.sh:第16行:grou

  • 问题内容: 我有想要应用于多个表的代码,而不是简单地复制和替换表名,而是想使用某种循环或游标来简化代码。 我设想设置一个表名数组,并使用索引遍历该列表,检索每个表名,并在适用于我的代码的情况下使用动态SQL散布表名。 据我所知,由于在SQL中没有“数组”构造,因此我不确定这将如何工作。 关于如何解决这个问题的任何想法? 问题答案: 这是一种实现方法:

  • 问题内容: 我正在做一个项目,但是我不能使用任何现有的Java数据结构(即ArraysList,树等) 我只能使用数组。因此,我需要用新的内存动态更新数组。 我正在从一个文本文件中读取数据,并且为数组内存预分配了100: 现在,此功能适用于100个以下列表项。br.readline是经过缓冲的阅读器,它遍历文本文件的每一行。然后,我将每个单词存储到列表中,然后增加索引(wordCount)。 但是

  • 问题内容: 我正在使用ajax google maps脚本,需要在for循环中创建动态变量名称。 我想的是:,,等。我想这有什么问题 Firebug给了我这个: 问题答案: 为此使用数组。

  • 问题内容: 我不知道这是否是一个愚蠢的问题,但是我需要在不使用递归的情况下动态更改for循环的数量。 例如,如果n = 3,则需要3个嵌套的for循环。 如果n = 5: 有没有什么方法可以做到这一点而无需递归?另一个问题:Java中多重调度的用途是什么?我正在尝试用一种方法编写代码,它应该在参数的不同情况下运行不同的事件。否,如果声明/三元经营者/案件。 注意:我只能使用一种方法(部分问题),并

  • 我正在从Sahni的“C语言数据结构基础”中学习数据结构。在使用动态数组的循环队列中,作者提到了以下几点, 假设capacity是循环队列的初始容量,我们必须首先使用realloc增加数组的大小,这将把最大容量元素复制到新的数组中。为了获得正确的循环队列配置,我们必须将右段中的元素(即元素a和B)滑动到数组的右端(参见图3.7.d)。数组加倍和向右滑动一起最多复制2*容量-2个元素。