在我开始之前,我不确定这是一个编程错误,我对PHP逻辑的误解,还是我使用的PHP程序的错误。我正在检查文件。我构建单词树数组,每个条目的形式为 array(string,count),其中 count 是字符串在文档中出现的次数(到目前为止)。一旦我将一个项目添加到单词树中,我必须将它留在原地,因为程序的其他部分不保留该字符串的副本,而是将索引保留在可以找到该字符串的表中。但是,该程序创建了一个 BTree,它是一个索引列表,可用于按顺序列出字符串并允许对字符串进行二进制搜索。下面的代码用于查找传递的字符串(单词)的索引,并在必要时将字符串添加到单词树中。
function PinWord($word,&$wordTree,&$bTree,&$WTI) {
global $BTreeA, $BTreeO;
$F=0; $L=count($wordTree)-1;
if (count($wordTree)!=count($bTree)) exit ("mismatch at L=$L"); // should never happen
if ($L<0) {// first time through ($WTI=-1 initially)
$wordTree[++$WTI]=array($word,1);
$bTree[0]=0;
return 0;
}
while ($F<=$L) {// do a binary search for the string
$i=intval(($F+$L)/2);
$j=$bTree[$i];
$test=$wordTree[$j][wv];
if ($word==$test) {
$wordTree[$j][wc]++; // bump count
return $j; } //found it
if ($word<$test)
$L=--$i; // change upper limit
else $F=++$i; // change lower limit
}
$WTI=count($wordTree); // redundant if everything working
$bt=array(); // going to rebuild $bTree
foreach($wordTree as $k => $A) $bt[$A[wv]]=$k;
if (count($wordTree)!=count($bt)) exit("duplicate words in word tree"); // shouldn't happen
if (array_key_exists($word,$bt)) {//oops shouldn't happen
Debug_M("misplaced key i=$i t=$bt[$word] key='$word'");// report error
return $bt[$word];}// out of order, return anyway
$bt[$word]=$WTI;
ksort($bt);//sort strings in ascending order
$bTree=array_values($bt);// replace $Btree
$wordTree[]=array($word,1);
if ($wordTree[$WTI][wv]!=$word) exit ("really bad, $word not same as ".$wordTree[$WTI][wv]."'");
if (count($wordTree)!=count($bTree)) exit ("mismatch B at $WTI");
return $WTI;
}
程序有两个单词 Trees。一棵树只包含所有字符都是(英语)字母表中的字母的字符串。该逻辑适用于该树(因此它似乎不是编码错误)。另一棵树只包含不包含任何此类字母的字符串。那棵树被搞砸了。有时 bTree 的顺序不正确,有时重复的字符串会添加到新的 Word-Tree 中。我不知道如何逃避 array_key_exists 测试。这是主要问题。 辅助问题:“ksort”好像开销很大。关于如何使用 array_slice、array_merge 以及变量 $word 和 $test 的任何想法。您认为拥有多个 bTrees 会有所帮助吗(字符串的每个第一个字母一个,或者字符串的每个长度一个)。这可以帮助更快地找到字符串。