我目前正在使用循环将值迭代到 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。