循环调用进程并在 Tcl 中分配值



我目前正在使用循环将值迭代到 Tcl 中的进程(邻居)中。

for {set i 0} {$i < $val(nn)} {incr i} {
for {set j 0} {$j < $val(nn)} {incr j} {
$ns at 0.0 "neighbors $node($i) $node($j) $i $j"
}
}

以上允许我需要进入该过程的所有值。但是,在流程内部,某些值被分配(到列表),不再需要循环访问。该过程的简短片段:

} else {
puts "..... Do nothing ....  $nd1 - $nd2"
if {([lsearch -exact $heads $nd1] != -1) || ([lsearch -exact $members $nd1] != -1) } { 
incr $nd1 
}
}

这是流程中循环的结束。puts只是一个标记,但它检查项目是否包含在 2 个列表之一中。如果它在任一列表中,请递增它,然后移动到下一个可能的值。该值不再需要检查/循环,因为它已经放在列表中。

如何防止继续使用该值?"进程调用"循环将始终覆盖进程中发生的情况,因此即使分配的值也将继续使用。有没有不同的方法来调用 Tcl 中的进程?或者至少,在 Tcl 中向进程提供值的不同方法?或者我猜,把它们拉出来?

请注意,这是我想要馈送到的过程(n1 和 n2 是内存位置,nd1 nd2 是实际的数字标识符)

set heads {}
set members {}

proc neighbors {n1 n2 nd1 nd2} {
global heads members bool allNodes 
puts "Members --- $members"
puts "heads --- $heads"
if {([lsearch -exact $heads $nd1] == -1) && ([lsearch -exact $members $nd1] == -1) } { 
lappend heads $nd1
set currentHead $n1
puts "Current Head: $currentHead $n1 $nd1"
} else {
puts "..... Do nothing ....  $nd1 - $nd2"
if {$nd1 in $heads || $nd1 in $members} then return
#here I want it to go to the next nd1 value and NEVER use it again if it 
#has already been processed 
}
#Otherwise, do neighbor test with nd2 

如果neighbors操作是对称的(通常是真的),你可以像这样检查所有内容:

for {set i 0} {$i < $val(nn)} {incr i} {
for {set j $i} {$j < $val(nn)} {incr j} {
$ns at 0.0 [list neighbors $node($i) $node($j) $i $j]
}
}

内部循环从$i开始(如果您不想对照自身检查,则为[expr {$i - 1}])而不是零。这确保了$j始终不小于$i,有效地(大约)将您需要做的工作量减半。 (样式点:使用[list ...]来准备代码以供以后执行被认为是好的风格,而不是"...";前者更有效,后者在处理可能包含空格的值时有一些丑陋的情况。

你不能做的(至少不容易;可能有一种方法可以做到这一点)是使用neighbors操作的结果来阻止将来对neighbors的调用发生,因为你已经安排它们在他们中的任何一个可能表达意见的时候发生。在您的情况下,保留状态变量并检查它是否有进行早期拒绝的选项可能更容易。这是使用延迟命令调用而不是直接调用的基本限制:将值传回去做一些事情,比如跳过未来的迭代是相当困难的(在Tcl 8.6之前非常棘手;这coroutine大大简化了任务)。

感觉你想这样做:

proc neighbors {n1 n2 nd1 nd2} {
global heads members bool allNodes 
if {$nd1 in $heads || $nd2 in $members} then return
... do the neighborly stuff ...
}

有关in运算符,请参阅 https://tcl.tk/man/tcl8.6/TclCmd/expr.htm#M15。

最新更新