Brain Teaser:我自己发起了这个问题,但完全陷入困境。
我想创建所有可能长度的所有字符的所有可能组合。假设,[a-z]组合1个长度,然后[a-z]组合2个长度,依此类推,直到达到最大长度。
这可以通过迭代循环很容易地完成。
3长度的例子:
proc triples list {
foreach i $list {
foreach j $list {
foreach k $list {
puts [list $i $j $k]
}
}
}
}
但是,它应该解决使用较少的循环(循环需要是动态的)
set chars "abcdefghijklmnopqrstuvwxyz"
set chars [split $chars ""]
set complete_length [llength $chars]
set start 0
set maximum_length 15
while {1} {
if {$start > $maximum_length} {
break
}
for {set i [expr $maximum_length-$start]} {$i >= 0} {incr i -1} {
# dump combinations
}
incr start
}
在这个块中,我应该应用什么算法或方法?任何建议/帮助/代码将不胜感激。
答案 0 :(得分:0)
“组合”这个词通常用得太普遍,因此可以用许多不同的方式来解释。假设您有26个不同元素的源列表,英文字母,并且您希望选择其中3个并且合并在3个元素的目的地列表中:
AHM
被视为与HAM
相同的组合吗?定义“合并”。您的第一个示例打印permutations,而不是combinations。如果这就是你想要的,那么easiset方式就是一个递归过程。组合生成起来更复杂。
修改强>
我为Project Euler程序编写了这个程序。它选择所有元素,但也许你可以修改它来选择n。它将命令前缀作为参数,因此您不必存储所有排列。
package require Tcl 8.5.0
proc forEachPerm {list cmdPrefix} {
_forEachPerm {} $list $cmdPrefix
}
proc _forEachPerm {head list cmdPrefix} {
if {![llength $list]} {
{*}$cmdPrefix $head
} else {
for {set i 0} {$i < [llength $list]} {incr i} {
_forEachPerm [concat $head [lrange $list $i $i]] [lreplace $list $i $i] $cmdPrefix
}
}
}
# example use:
forEachPerm {a b c} {apply {{list} {puts [join $list]}}}