搜索tcl列表的最有效方法

时间:2015-10-13 15:45:58

标签: list tcl

我有一个如下的tcl列表。

set mylist [list a b c d e]; # could be more

现在我正在进行一些处理,如果列表包含项目" c"," d"," e"。但是,当且仅当列表具有以下任一值时,我才需要跳过该处理:

set mylist [list a];

OR

set mylist [list b];

OR

set mylist [list a b];

因此,如果mylist是以上三种中的任何一种,我跳过处理。但是,假设列表中除了上述三种组合之外还有其他任何值,我都会进行处理。

如果列表中包含三种组合中的任何一种,最有效的搜索方式是什么。

我有满足我要求的基本代码,但我正在寻找更有效的方法,因为我对tcl容器不太熟悉。

set mylist [list a];

if {[llength $mylist] == 2 && ([lindex $mylist 0] eq "a" || [lindex $mylist 0] eq "b") && ([lindex $mylist 1] eq "a" || [lindex $mylist 1] eq "b")} {
  puts "1. skip the processing"
} elseif {[llength $mylist] == 1 && ([lindex $mylist 0] eq "a" || [lindex $mylist 0] eq "b")} {
  puts "2. skip the processing"
} else { 
  puts "Do the processing" 
}

我想知道是否有其他有效的方法来执行相同的操作。

1 个答案:

答案 0 :(得分:2)

if {$mylist in {a b {a b}}} {
    puts "skip the processing"
}

列表不是字符串,但我们通常可以将列表与字符串进行比较以获得相等和顺序。具有单个元素“a”的列表与字符串“a”相当。如果您想知道给定字符串是否等于问题中的任何列表,最简单的方法是检查列表的值是否是列表{a b {a b}}的成员。

注意: 此特定解决方案一般不会解决列表相等的所有方面。它适用于有效的情况。

<强>效率

将列表与字符串进行比较是否真的有效,这会导致自动重复重建数据的内部表示(“闪烁”)。实际上,它是。如果比较程序

proc foo1 mylist {
    set a 0
    if {$mylist in {a b {a b}}} {set a 92}
    return $a
}

proc foo2 mylist {
    set a 0
    if {$mylist in [list [list a] [list b] [list a b]]} {set a 92}
    return $a
}

然后foo1似乎比foo2更快(不同的机器可能产生不同的结果)。

在条件评估代码中构建一个列表似乎并没有增加太多时间。这个程序

proc foo3 mylist {
    set a 0
    set x [list [list a] [list b] [list a b]]
    if {$mylist in $x} {set a 92}
    return $a
}

速度介于foo1foo2之间,但不会明显快于foo2

也可以通过调用lsearch

来做到这一点
proc foo4 mylist {
    set a 0
    set x [list [list a] [list b] [list a b]]
    if {[lsearch $x $mylist] >= 0} {set a 92}
    return $a
}

proc foo5 mylist {
    set a 0
    set x [list [list a] [list b] [list a b]]
    set i [lsearch $x $mylist]
    if {$i >= 0} {set a 92}
    return $a
}

foo2foo3相当。

(如果需要说明,lsearchin运算符更通用,提供例如不区分大小写的查找,正则表达式查找等。如果您需要这些内容,{{1}是最好的选择。)

在另一台机器上安排程序后,我删除了大部分关于速度的观察和理论,结果显示出截然不同的结果。但是,lsearch在这两台机器上的速度始终更快。由于该代码比其他替代方案更简单,我想说这是实现它的方法。但可以肯定的是,人们需要使用自己的机器,白名单和要执行的代码来计算程序。

最后,如果I / O发生在程序内部,那么这一切都不重要,因为I / O会比其他任何东西慢得多。

文档:iflistlsearchprocputsreturnset