proc Fibonacci {x} {
set n(0) 0; set n(1) 1
set i 2
while {$i <= $x} {
set n($i) [expr n($i-2) + n($i-1)]
incr i
}
return $n($i)
}
set y [Fibonacci 10]
puts "$y"
Run Code Online (Sandbox Code Playgroud)
在编译上述程序时,我收到以下错误.请纠正我
你的问题在本声明中是双重的:
set n($i) [expr n($i-2) + n($i-1)]
Run Code Online (Sandbox Code Playgroud)
首先,你必须得到n($i-2)它的名称,而不是它的名字,所以你应该改为:
set n($i) [expr {$n($i-2) + $n($i-1)}]
Run Code Online (Sandbox Code Playgroud)
我还介绍{}了使它expr更整洁,更不容易出错.但是,这仍然无法工作,因为$i-2在尝试索引n数组之前不会计算,所以你需要这样:
set n($i) [expr {$n([expr {$i-2}]) + $n([expr {$i-1}])}]
Run Code Online (Sandbox Code Playgroud)
固定?不,这条线仍然是错的:
return $n($i)
Run Code Online (Sandbox Code Playgroud)
你看,你索引$i,但在你的循环中,你写入n($i)和之后立即增加i,所以它将比最后一个元素高一个.您需要将其更改为:
return $n($x)
Run Code Online (Sandbox Code Playgroud)
这为您的代码提供了一个工作版本:
proc Fibonacci {x} {
set n(0) 0
set n(1) 1
set i 2
while {$i <= $x} {
set n($i) [expr {$n([expr {$i-2}]) + $n([expr {$i-1}])}]
incr i
}
return $n($x)
}
set y [Fibonacci 10]
puts "$y"
Run Code Online (Sandbox Code Playgroud)
这仍然可以做到,但是,让我们使用for而不是while:
proc Fibonacci1 {x} {
set n(0) 0
set n(1) 1
for {set i 2} {$i <= $x} {incr i} {
set n($i) [expr {$n([expr {$i-2}]) + $n([expr {$i-1}])}]
}
return $n($x)
}
Run Code Online (Sandbox Code Playgroud)
让我们用一个列表替换那个数组,语义在这里工作得更好:
proc Fibonacci2 {x} {
set n [list 0 1]
for {set i 2} {$i <= $x} {incr i} {
lappend n [expr {[lindex $n end] + [lindex $n end-1]}]
}
return [lindex $n end]
}
Run Code Online (Sandbox Code Playgroud)
这里的数组很无用,因为它们实际上是tcl中的关联容器,列表是一个顺序容器,你在这个算法中显然使用了它.你可以在速度上看到这个,这是我在计算机上用tcl 8.6得到的:
time {Fibonacci1 100} 10000
64.1805 microseconds per iteration
time {Fibonacci2 100} 10000
23.9295 microseconds per iteration
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
671 次 |
| 最近记录: |