这个问题最好是递归处理。特别是,为特定计数器生成计数会导致回调以处理链中的下一个计数器。需要注意的是按照正确的顺序将结果拼凑在一起(有几种方法可以实现),但下面的方法很好,因为它将数据生成为列表列表,从而可以对其进行进一步处理,根据您的选择打印。
请注意使用默认参数关闭递归。通过使用包装程序可以避免这种情况,但这是一种改进。
proc genseq {definition {current {}}} {
# Get the next part of the definition
lassign [lindex $definition 0] columns prefix limit
set definition [lrange $definition 1 end]
set result {}
for {set i 0} {$i < $limit} {} {
# Handle the appending of bits relating to the counter at the current level
set cur $current
foreach c $columns {
lappend cur "$prefix$i"
incr i
}
# If we have more definition to process, recursive call. Otherwise just accumulate
if {[llength $definition] > 0} {
lappend result {*}[genseq $definition $cur]
} else {
lappend result $cur
}
}
return $result
}
让我们来测试一下:
set seqinfo {
{{XD} PD 2}
{{XB} PB 4}
{{XA0 XA1} PA 4}
}
# A bit of trickery to get approximately the right output format
puts \{\{[join [genseq $seqinfo] "\}\n\{"]\}\}
,输出结果。
{{PD0 PB0 PA0 PA1}
{PD0 PB0 PA2 PA3}
{PD0 PB1 PA0 PA1}
{PD0 PB1 PA2 PA3}
{PD0 PB2 PA0 PA1}
{PD0 PB2 PA2 PA3}
{PD0 PB3 PA0 PA1}
{PD0 PB3 PA2 PA3}
{PD1 PB0 PA0 PA1}
{PD1 PB0 PA2 PA3}
{PD1 PB1 PA0 PA1}
{PD1 PB1 PA2 PA3}
{PD1 PB2 PA0 PA1}
{PD1 PB2 PA2 PA3}
{PD1 PB3 PA0 PA1}
{PD1 PB3 PA2 PA3}}
我会放在标题和额外的空间行作为练习。 (另外,Tcl没有用逗号分隔列表;实际上,逗号是普通字符,在表达式之外对它们没有什么特别之处。)
你有什么尝试?将XA1设置为单独的映射条目将使您的生活更轻松。 –
这是一个非平凡的转换,正是因为来自单个序列计数器的值在多列中使用的方式。 –