我想根据动态列表进行一些排序。让我解释一下 我使用的是tcl版本8.4,我无法更改,必须使用
list1 = {{a b c} {c b c a} {b b a}} ..... 1st input data
列表1是一个tcl列表,其中有3个成员,它们以任何顺序形成不同类型的子列表,甚至每次都会更改。例如,下次列表1将是:
list1 = {{c} {b c a} {b c} {a c a c}} ..... 2nd input data (for next time consideration)
现在我想以这样的方式对它们进行排序:如果我使用它们周围的循环或lsort
或string compare
或任何其他tcl命令,新的tcl列表应包含基于a的单个成员优先。就像我们有上升/下降一样。
请注意,两种情况下,单个子列表长度都在增加和减少,同时从a,b,c也继续旋转。
在我的情况下,我希望“a”具有最高优先级,然后是“b”,然后是“c”(a-> b-> c)
因此,在第一次迭代完成处理后的输出应为:
$> puts $new_list1
$> {a a a} # as out of 3 sublists a is present in them and it gets highest priority.
类似地,在第二次迭代完成处理后的输出应为:
$> puts $new_list1
$> {c a b a} # as you can see that list1 1st element is c so it gets output as is, second sublist has b c and a so `a` gets outputted, 3rd sublist is b and c so `b` gets outputted
让我知道你的想法。
提前致谢!
答案 0 :(得分:0)
首先,我将研究构建这种数据结构,以便您不必对所有子列表进行排序 - 例如,使用像二进制搜索一样简单的算法linsert
每个元素到每个子列表的排序索引。
其次,我会考虑你是否需要像你想象的那样多的“优化”。通常,最好的解决方案(由于可维护性)是最明显的事情:对子列表进行排序,然后使用循环,如下所示:
# construct a new list of sorted sublists
foreach sublist $list {
lappend presorted_list [lsort $sublist]
}
# given a reference to a list of sorted lists, simultaneously build (1) a list of
# each sublist's first element and (2) a list of the each sublist's remaining
# elements, so that the former can be returned, and the latter can be set by
# reference for the next iteration (and will have omitted any empty sublists)
proc process_once {presorted_list_ref} {
upvar $presorted_list_ref presorted_list
foreach sublist $presorted_list {
if {[llength $sublist] > 0} {
lappend returning_list [lindex $sublist 0]
lappend remaining_list [lrange $sublist 1 end]
}
}
set presorted_list $remaining_list
return $returning_list
}
set iter_1 [process_once presorted_list]
set iter_2 [process_once presorted_list]
如果您不能以开始排序的子列表的方式预处理或构建原始列表,我认为没有更好的方法可以做到这一点。除非从排序的子列表开始,否则您无法决定每个子列表中的哪个项目必须输出,而不检查所有项目 - 所以您也可以排序一次,这样您就会知道始终采用第一个每个子列表的项目,正如我上面编码的那样。
以循环形式,如果您不需要一次特定地检索一次迭代,
foreach sublist $list {
lappend presorted_list [lsort $sublist]
}
while {[llength $presorted_list] > 0} {
foreach sublist $presorted_list {
if {[llength $sublist] > 0} {
lappend returning_list [lindex $sublist 0]
lappend remaining_list [lrange $sublist 1 end]
}
}
#
# do stuff with $returning_list
#
set presorted_list $remaining_list
}