我编写了以下代码块,以查找节点网格中是否存在单词。
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)一旦我发现所有" r" s连接到" a"我现在在,我检查是否有任何" t" s连接到" 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来返回所有具有特定值的节点,或者false和findAllConnectedTo返回所有具有特定值的节点连接到未包含在"不使用" notInLoc list。
答案 0 :(得分:2)
你需要将结果通过所有嵌套的上下文传递到顶部,因为找到的单词最终将返回true,但它将在上层消失(继续循环并返回false)。试试这个:
if ($list2 = $this->findAllConnectedTo($node, $word[$i], $notInLoc)) {
if ($i == strlen($word) - 1 || $this->inner($word, $list2, $i, $notInLoc)) {
return true;
}
}
接下来我会照顾$word
针刺过来的。它对于所有上下文都保持不变 - 只有指针变化。