tcl 查找列表的最大元素

Lig*_*ami 1 tcl

我是 tcl 新手,我试图获取给定列表中的最大元素我编写了一个打印最大值的函数,但它无法正常工作,这是代码

proc findmax { items } {
  set max 1
  foreach i $items { 
    if { $i > $max } {
      set $max $i
    }
  }
  puts "max is = $max"
}
Run Code Online (Sandbox Code Playgroud)

我这样调用该函数:

findmax $items
Run Code Online (Sandbox Code Playgroud)

这是我通过的列表:

set items { 12 2 5 4 2 6 7 55 8 9 6 4}
Run Code Online (Sandbox Code Playgroud)

但它输出 1 而不是预期的 55

Don*_*ows 6

你的问题是这一行:

set $max $i
Run Code Online (Sandbox Code Playgroud)

在 Tcl 中,$字符意味着从命名变量中读取并将该值用作命令的参数(可能是命令的一部分)。总是这个意思。没有例外(当然,除非用反斜杠引用或在{大括号中})。因此,在循环的第一次迭代中,您将得到(替换后):

set 1 12
Run Code Online (Sandbox Code Playgroud)

变量名1是合法的,但不寻常,不是您想要的。为了使算法正常工作,您需要为命令指定set要设置的变量的名称max,结果如下:

set max $i
Run Code Online (Sandbox Code Playgroud)

将在第一次迭代时替换为:

set max 12
Run Code Online (Sandbox Code Playgroud)

看起来不错!未来编程的一个好的经验法则是,如果命令操作变量(设置或更新它),那么您需要传递变量的名称,而不是从中检索的值。


获取列表最大值的标准方法是单行:

set max [tcl::mathfunc::max {*}$items]
Run Code Online (Sandbox Code Playgroud)

这使用内置函数max(位于::tcl::mathfunc命名空间中)并将列表的内容作为items多个参数传递,所有这些都作为一个步骤。该{*}$序列是变量读取语法规则与列表扩展规则的组合,您可能还没有真正考虑过。然而,编写自己的最大值查找器作为学习练习仍然是一个很好的练习。