我编写了下面的代码块来查找一个单词是否存在于节点网格中。
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;
}
这个"工作"并且通过了我所有的3个字母的单词测试用例,因为我已经硬编码了我正在寻找的字符,并且我知道这个单词有多长。但是我需要做的是传入任何单词,不管长度和字母,如果我发现该单词不符合所有这些限制,则返回true。
在这里总结一下算法:
1)我找到包含第一个字符"a"的所有节点,并获得这些节点的列表。这是我的出发点。
2)对于每个"a",我正在寻找与它相连但不在我已经使用的位置的所有"r"。(每个节点都有一个位置键,该键在查看它时存储在notInLoc数组中。我意识到这可能会突破,因为notInLoc只在我第一次进入函数时被重置,所以每次我通过foreach时,它都会将相同的位置推入。
3)一旦我找到了所有与"a"相连的"r",我检查是否有任何与"r"相连的"t"。如果至少有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返回具有特定值的所有节点,或false和findAllConnectedTo返回具有连接到不包含在"请勿使用"notInLoc列表上的节点的特定值的所有节点。
您需要通过所有嵌套上下文将result传递到顶部,因为find word最终将返回true,但它将在上层消失(继续循环并返回false)。试试这个:
if ($list2 = $this->findAllConnectedTo($node, $word[$i], $notInLoc)) {
if ($i == strlen($word) - 1 || $this->inner($word, $list2, $i, $notInLoc)) {
return true;
}
}
接下来我要处理$word
不必要地传递。它在所有上下文中保持不变——只有指针发生了变化。