使这 php 代码块动态或递归
Make this block of php code dynamic or recursive
我编写了以下代码块来查找某个单词是否存在于节点网格中。
function findWord() {
$notInLoc = [];
if ($list = $this->findAll("a")) {
foreach($list as $node) {
$notInLoc[] = $node->loc;
if ($list2 = $this->findAllConnectedTo($node, "r", $notInLoc)) {
foreach($list2 as $node2) {
$notInLoc[] = $node2->loc;
if ($list3 = $this->findAllConnectedTo($node2, "t", $notInLoc)) {
foreach($list3 as $node3) {
return true;
}
}
}
}
}
}
return false;
}
这个 "works" 并通过了我所有的 3 个字母的单词测试用例,因为我已经对要查找的字符进行了硬编码并且我知道这个单词有多长。但是我需要做的是传入任何单词,无论长度和字母如何,如果我找到了所有这些限制的单词,return true。
在这里总结算法:
1) 我找到所有包含第一个字符 "a" 的节点,并获得这些节点的列表。这就是我的出发点。
2) 对于每个 "a",我正在寻找与其连接但不在我已经使用的位置的所有 "r"。 (每个节点都有一个位置键,在查看时该键存储在 notInLoc 数组中。我意识到这可能会中断,因为 notInLoc 只是在我第一次进入该函数时才被重置,所以每次我通过 foreach它不断推入相同的位置。
3) 找到所有连接到我当前所在的 "a" 的 "r" 后,我检查是否有任何 "t" 连接到"r"s。如果至少有 1 个 "t" 连接,那么我知道这个词已找到。
我无法重构它以使其动态化。我会告诉你我正在使用的想法,但它被打破了。
function inner($word, $list, $i = 0, $notInLoc = []) {
$i++;
foreach($list as $node) {
$notInLoc[] = $node->loc;
if ($list2 = $this->findAllConnectedTo($node, $word[$i], $notInLoc)) {
if ($i == (strlen($word) - 1)) {
return true;
} else {
$this->inner($word, $list2, $i, $notInLoc);
}
}
}
return false;
}
function findWord2($word) {
if ($list = $this->findAll($word[0])) {
return $this->inner($word, $list);
}
return false;
}
我知道还有其他方法可以解决这样的问题,但我需要它只使用函数 findAll 来工作,returns 所有具有特定值的节点,或者 false 和 findAllConnectedTo returns 所有具有特定值的节点连接到 "Do Not Use" notInLoc 列表中未包含的节点。
您需要将结果通过所有嵌套上下文传递到顶部,因为找到的单词最终会 return 为真,但它会在上层消失(继续循环和 return 假)。试试这个:
if ($list2 = $this->findAllConnectedTo($node, $word[$i], $notInLoc)) {
if ($i == strlen($word) - 1 || $this->inner($word, $list2, $i, $notInLoc)) {
return true;
}
}
接下来我会处理 $word
针刺般的传递。它在所有上下文中都保持不变 - 只有指针发生变化。
我编写了以下代码块来查找某个单词是否存在于节点网格中。
function findWord() {
$notInLoc = [];
if ($list = $this->findAll("a")) {
foreach($list as $node) {
$notInLoc[] = $node->loc;
if ($list2 = $this->findAllConnectedTo($node, "r", $notInLoc)) {
foreach($list2 as $node2) {
$notInLoc[] = $node2->loc;
if ($list3 = $this->findAllConnectedTo($node2, "t", $notInLoc)) {
foreach($list3 as $node3) {
return true;
}
}
}
}
}
}
return false;
}
这个 "works" 并通过了我所有的 3 个字母的单词测试用例,因为我已经对要查找的字符进行了硬编码并且我知道这个单词有多长。但是我需要做的是传入任何单词,无论长度和字母如何,如果我找到了所有这些限制的单词,return true。
在这里总结算法:
1) 我找到所有包含第一个字符 "a" 的节点,并获得这些节点的列表。这就是我的出发点。
2) 对于每个 "a",我正在寻找与其连接但不在我已经使用的位置的所有 "r"。 (每个节点都有一个位置键,在查看时该键存储在 notInLoc 数组中。我意识到这可能会中断,因为 notInLoc 只是在我第一次进入该函数时才被重置,所以每次我通过 foreach它不断推入相同的位置。
3) 找到所有连接到我当前所在的 "a" 的 "r" 后,我检查是否有任何 "t" 连接到"r"s。如果至少有 1 个 "t" 连接,那么我知道这个词已找到。
我无法重构它以使其动态化。我会告诉你我正在使用的想法,但它被打破了。
function inner($word, $list, $i = 0, $notInLoc = []) {
$i++;
foreach($list as $node) {
$notInLoc[] = $node->loc;
if ($list2 = $this->findAllConnectedTo($node, $word[$i], $notInLoc)) {
if ($i == (strlen($word) - 1)) {
return true;
} else {
$this->inner($word, $list2, $i, $notInLoc);
}
}
}
return false;
}
function findWord2($word) {
if ($list = $this->findAll($word[0])) {
return $this->inner($word, $list);
}
return false;
}
我知道还有其他方法可以解决这样的问题,但我需要它只使用函数 findAll 来工作,returns 所有具有特定值的节点,或者 false 和 findAllConnectedTo returns 所有具有特定值的节点连接到 "Do Not Use" notInLoc 列表中未包含的节点。
您需要将结果通过所有嵌套上下文传递到顶部,因为找到的单词最终会 return 为真,但它会在上层消失(继续循环和 return 假)。试试这个:
if ($list2 = $this->findAllConnectedTo($node, $word[$i], $notInLoc)) {
if ($i == strlen($word) - 1 || $this->inner($word, $list2, $i, $notInLoc)) {
return true;
}
}
接下来我会处理 $word
针刺般的传递。它在所有上下文中都保持不变 - 只有指针发生变化。