【问题标题】:Recursive Programming in Tcl for PermutationsTcl 中用于排列的递归编程
【发布时间】:2016-01-26 23:21:57
【问题描述】:

我有一个未知的模式,并且给我的 getCombos proc 提供了未知数量的数据。

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

例如:

# 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 A A 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 需要递归。

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

【问题讨论】:

    标签: algorithm recursion tcl permutation


    【解决方案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
    

    【讨论】:

    • 非常接近,我现在正在修改代码以仅显示我想要的内容,它有点太健壮了,我只想要这个列表的一个子集。非常感谢!
    • @LegitStack 我提交并更新了您示例中的子集。
    猜你喜欢
    • 1970-01-01
    • 2018-04-10
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 2011-06-18
    • 2011-07-23
    • 1970-01-01
    相关资源
    最近更新 更多