我有一个看起来像这样的字典:
未排序:
12 {12 489} 29 {89 12} 27 {301 302} 26 {489 329} 8 {89 302} 55 {44 301}
我想这样排序:
55 {44 301} 27 {301 302} 8 {89 302} 29 {89 12} 12 {12 489} 26 {489 329}
如您所见,大多数情况下,前一个条目的第二个键值与下一个条目的第一个键条目相同。 (最后两个条目中的12
和489
)
这虽然没有要求。第二个和第三个条目的302
也满足第二个和第三个条目中存在的“链”的要求。
我唯一要做的就是以这种方式对这些条目进行排序,使大括号中的值形成一个不间断的链。
如果结果在示例中显示或者是否镜像,则无关紧要。
从TCL 8.6开始,我可以使用步幅做类似于Sort Tcl dict by value的操作。但我坚持这个(Tcl8.5.9)版本。最简单的方法是什么?
答案 0 :(得分:1)
我不知道这是否是最简单的方法:
set x [dict create 12 {12 489} 29 {89 12} 27 {301 302} 26 {489 329} 8 {89 302} 55 {44 301}]
# transform the dict into a list of lists
dict for {k v} $x {lappend unsorted [list $k $v]}
lappend sorted [lindex $unsorted 0]
set unsorted [lrange $unsorted 1 end]
# keep going until there's nothing more to add to the sorted list
while {[llength $unsorted] != 0} {
set changed false
for {set idx 0} {$idx < [llength $unsorted]} {incr idx} {
set elem [lindex $unsorted $idx]
lassign [lindex $elem end] a b
set head [lindex $sorted 0 end]
set tail [lindex $sorted end end]
if {$a in $head || $b in $head} {
set sorted [linsert $sorted 0 $elem]
set changed true
} elseif {$a in $tail || $b in $tail} {
lappend sorted $elem
set changed true
}
if {$changed} {
set unsorted [lreplace $unsorted $idx $idx]
break
}
}
# avoid infinite loop if the unsorted list is not empty, but
# contains nothing to add to the sorted list
if {! $changed} break
}
foreach elem $sorted {dict set y {*}$elem}
puts "Unsorted: $x"
puts "Sorted: $y"
Unsorted: 12 {12 489} 29 {89 12} 27 {301 302} 26 {489 329} 8 {89 302} 55 {44 301}
Sorted: 55 {44 301} 27 {301 302} 8 {89 302} 29 {89 12} 12 {12 489} 26 {489 329}