algorithm - Tcl 中用于排列的递归编程

标签 algorithm recursion tcl permutation

我的 getCombos 过程有一个未知的模式和未知数量的数据。

我需要找到一种方法,在模式允许的情况下递归地在数据中生成尽可能多的匹配项。

例如:

# pattern  | data
# {0 1 2}    {0 {{A B C} {AA BB CC}}\
              1 {{D E F} {DD EE FF}}\
              2 {{G H I} {GG HH II}}\
             }
# returns this list: (split out on multiple lines are for your viewing pleasure)
  { A  E  I  }\
  { A  E  II }\
  { A  EE I  }\
  { A  EE II }\
  { AA E  I  }\
  { AA E  II }\
  { AA EE I  }\
  { AA EE II }\

数据将始终是一个字典列表,其中的键从 0 到 n。

模式将始终是 0 到 n 的某种混合(在本例中为 {0 1 2} 或 {2 0 1} 等)。

这就是我认为我不能使用简单递归的原因——因为我不知道模式中有多少元素,也不知道数据下的每个值中有多少元素,我也不知道数据中会有多少键。

我唯一知道的是数据值元素内的元素数量与模式中的元素数量相匹配(例如,[llength {0 1 2}] 是 3和 [llength {A B C}] 是 3) 这非常重要,因为我正在按顺序从 $data 中提取数据。

请允许我举一个反例来强调模式影响它的方式:

# pattern  | data
# {1 2 1}    {0 {{A B C} {AA BB CC}}\
              1 {{D E F} {DD EE FF}}\
              2 {{G H I} {GG HH II}}\
             }
# returns this list: (split out on multiple lines are for your viewing pleasure)
  { D  H  F  }\
  { D  H  FF }\
  { D  HH F  }\
  { D  HH FF }\
  { DD H  F  }\
  { DD H  FF }\
  { DD HH F  }\
  { DD HH FF }\

如您在上面的示例中所见,[dict get $data 0] 从未输入任何方程式。模式的第一个索引对应于值列表(A AA D DD G 和 GG)中第一组中的第一项,第二个匹配第二个(B BB E EE H 或 HH),第三个匹配第三个(C抄送 F FF I 或 II)。这些索引的实际值与应该使用的键相匹配。

最后,我需要根据模式对适当数据进行各种组合。

相当困惑。这是我一直在走的路,但正如您所看到的,我离拥有任何有值(value)的东西还很远:

proc getCombo {pattern data} {
  set g yes
  set i 0  ;# These counters must be replaced by recursive design
  set j 0
  set k 0
  set p 0
  while {$g} {
    puts [lindex [lindex [dict get $data $i] $j] [lindex $pattern $p]]
    puts " [lindex [lindex [dict get $data $j] $k] [lindex $pattern $p]]"
    if {$k == [llength [dict get $data $i]] } {
      set k 0
      set g no
    }
    if {$j == [llength [dict get $data $i]] } {
      set j 0
      incr k
      incr p
    }
    incr j
  }
#########################
  for {set z 0} {$z < [llength [dict get $data 0]]} {incr z} {
    for {set o 0} {$o < [llength [dict get $data 1]]} {incr o} {
      for {set t 0} {$t < [llength [dict get $data 2]]} {incr t} {
        for {set p 0} {$p < [llength $pattern]} {incr p} {
        }
      }
    }
  }
########################
  #foreach pat $pattern {
    foreach key [dict keys $data] {
    }
  #}
########################
  #return $newdata
}

有人知道我可以在这里做什么吗?我花了一整天的时间才想出上面的代码,但我并没有感觉更接近,但我现在有一种感觉,如果我要产生我想要的东西,我的过程需要递归。

感谢您给我的任何建议或指导!

最佳答案

编辑

下面为您提供示例中的子集。

set input {
  {1 2 1}
  {
    0 {{A B C} {AA BB CC}}
    1 {{D E F} {DD EE FF}}
    2 {{G H I} {GG HH II}}
  }
}

set pattern [lindex $input 0]
set data [lindex $input 1]

proc perm {pattern data {start 0} {result ""}} {

  set len [llength $pattern]
  set rlen [llength $result]

  if {$rlen == $len} {
    puts [join $result "\t"]
    return
  }

  for {set i $start} {$i < $len} {incr i} {
    set k [lindex $pattern $i]
    foreach {subset} [dict get $data $k] {
      set temp $result
      lappend temp [lindex $subset $rlen]
      perm $pattern $data [expr {$i + 1}] $temp
    }
  }
}

perm $pattern $data

输出:

D   H   F

D   H   FF

D   HH  F

D   HH  FF

DD  H   F

DD  H   FF

DD  HH  F

DD  HH  FF

全烫

set input {
  {1 2 1}
  {
    0 {{A B C} {AA BB CC}}
    1 {{D E F} {DD EE FF}}
    2 {{G H I} {GG HH II}}
  }
}

set pattern [lindex $input 0]
set data [lindex $input 1]

proc perm {pattern data {start 0} {result ""}} {

  set len [llength $pattern]

  if {[llength $result] == $len} {
    puts [join $result "\t"]
    return
  }

  for {set i $start} {$i < $len} {incr i} {
    set k [lindex $pattern $i]
    foreach {subset} [dict get $data $k] {
      foreach {value} $subset {
        set temp $result
        lappend temp $value
        perm $pattern $data [expr {$i + 1}] $temp
      }
    }
  }
}

perm $pattern $data

输出:

D   G   D

D   G   E

D   G   F

D   G   DD

D   G   EE

D   G   FF

D   H   D

D   H   E

D   H   F

D   H   DD

D   H   EE

D   H   FF

D   I   D

D   I   E

D   I   F

D   I   DD

D   I   EE

D   I   FF

D   GG  D

D   GG  E

D   GG  F

D   GG  DD

D   GG  EE

D   GG  FF

D   HH  D

D   HH  E

D   HH  F

D   HH  DD

D   HH  EE

D   HH  FF

D   II  D

D   II  E

D   II  F

D   II  DD

D   II  EE

D   II  FF

E   G   D

E   G   E

E   G   F

E   G   DD

E   G   EE

E   G   FF

E   H   D

E   H   E

E   H   F

E   H   DD

E   H   EE

E   H   FF

E   I   D

E   I   E

E   I   F

E   I   DD

E   I   EE

E   I   FF

E   GG  D

E   GG  E

E   GG  F

E   GG  DD

E   GG  EE

E   GG  FF

E   HH  D

E   HH  E

E   HH  F

E   HH  DD

E   HH  EE

E   HH  FF

E   II  D

E   II  E

E   II  F

E   II  DD

E   II  EE

E   II  FF

F   G   D

F   G   E

F   G   F

F   G   DD

F   G   EE

F   G   FF

F   H   D

F   H   E

F   H   F

F   H   DD

F   H   EE

F   H   FF

F   I   D

F   I   E

F   I   F

F   I   DD

F   I   EE

F   I   FF

F   GG  D

F   GG  E

F   GG  F

F   GG  DD

F   GG  EE

F   GG  FF

F   HH  D

F   HH  E

F   HH  F

F   HH  DD

F   HH  EE

F   HH  FF

F   II  D

F   II  E

F   II  F

F   II  DD

F   II  EE

F   II  FF

DD  G   D

DD  G   E

DD  G   F

DD  G   DD

DD  G   EE

DD  G   FF

DD  H   D

DD  H   E

DD  H   F

DD  H   DD

DD  H   EE

DD  H   FF

DD  I   D

DD  I   E

DD  I   F

DD  I   DD

DD  I   EE

DD  I   FF

DD  GG  D

DD  GG  E

DD  GG  F

DD  GG  DD

DD  GG  EE

DD  GG  FF

DD  HH  D

DD  HH  E

DD  HH  F

DD  HH  DD

DD  HH  EE

DD  HH  FF

DD  II  D

DD  II  E

DD  II  F

DD  II  DD

DD  II  EE

DD  II  FF

EE  G   D

EE  G   E

EE  G   F

EE  G   DD

EE  G   EE

EE  G   FF

EE  H   D

EE  H   E

EE  H   F

EE  H   DD

EE  H   EE

EE  H   FF

EE  I   D

EE  I   E

EE  I   F

EE  I   DD

EE  I   EE

EE  I   FF

EE  GG  D

EE  GG  E

EE  GG  F

EE  GG  DD

EE  GG  EE

EE  GG  FF

EE  HH  D

EE  HH  E

EE  HH  F

EE  HH  DD

EE  HH  EE

EE  HH  FF

EE  II  D

EE  II  E

EE  II  F

EE  II  DD

EE  II  EE

EE  II  FF

FF  G   D

FF  G   E

FF  G   F

FF  G   DD

FF  G   EE

FF  G   FF

FF  H   D

FF  H   E

FF  H   F

FF  H   DD

FF  H   EE

FF  H   FF

FF  I   D

FF  I   E

FF  I   F

FF  I   DD

FF  I   EE

FF  I   FF

FF  GG  D

FF  GG  E

FF  GG  F

FF  GG  DD

FF  GG  EE

FF  GG  FF

FF  HH  D

FF  HH  E

FF  HH  F

FF  HH  DD

FF  HH  EE

FF  HH  FF

FF  II  D

FF  II  E

FF  II  F

FF  II  DD

FF  II  EE

FF  II  FF

关于algorithm - Tcl 中用于排列的递归编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35025960/

相关文章:

python - 如何使用递归函数检查两个节点是否连接

linux - TCL 在 proc 之后调用另一个 proc

javascript - 通过 Ajax 获取服务器时间 - 我的代码有什么问题?

bash - 在 proc 内运行 proc 时期望失败

javascript - 邮政编码生成器 JQuery

java - 如何正确填写自定义数据结构以供 A* 算法使用? (警告 : LONG)

c++ - 退出整个递归堆栈

java - 查找以下代码的时间复杂度和大O

java - MineSweeper 揭示邻居帮助需要 java

c - 在 C 中使用递归打印字符串