用于排列的Tcl递归编程

时间:2016-01-26 23:21:57

标签: algorithm recursion tcl permutation

我有一个未知的模式,以及给我的getCombos proc提供的未知数据量。

我需要找到一种方法来递归地在模式允许的数据中产生尽可能多的匹配。

For Instance:

# 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) CC F FF I或II)。这些索引的实际值与应该使用的密钥匹配。

最后,我根据模式需要适当数据的每种组合。

相当令人困惑。这是我一直走下去的路,但正如你所看到的,我远没有任何有价值的东西:

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
}

有没有人知道我能在这做什么?它花了我一整天的时间来提出上面的代码并且我感觉不到任何接近,但我现在感觉如果我要生产我想要的东西,我的proc需要递归。

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

1 个答案:

答案 0 :(得分:1)

修改

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

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