在我开始之前,我不确定这是一个编程错误,我对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;
}
该程序有两个单词树。一棵树只保存所有字符都是(英语)字母表的字母的字符串。该逻辑对于该树工作正常(因此它似乎不是编码错误)。另一棵树只保存不包含任何此类字母的字符串。那棵树被弄乱了。有时bTree的顺序不正确,有时重复的字符串被添加到新的Word-Tree中。如何逃脱array_key_exists测试,我不知道。这是主要的问题。辅助问题:“ksort”似乎有很多开销。如何使用array_slice、array_merge以及变量$word和$test?你认为有多个bTree会有帮助吗(每个字符串的第一个字母都有一个,或者每个字符串的长度都有一个)。这可以帮助更快地找到字符串。调试我发现另一个奇怪的结果:
$SC=array("\n","\t"); $SCA=array('n','t');
$z2=str_replace($SC,$SCA,$z);
代码可以很好地处理制表符。但是,如果一行中有两个新行字符,则第二个字符将被替换(或者在新行之后插入“n”,或者替换新行之后的字符)。你应该可以复制它。
经过更多的调试,我得到了强烈的迹象表明,这是一个问题,与PHP我的Apache服务器正在使用。我用try it编辑器测试了以下代码
<?php
$Left_W=array(' 12',' 13 ',' “4 ',' 2 ',' 2. ',' 3 ',' 3 ',' 4 ',' 5. ',' 6 ');
$Right_W=array(' 12 ',' 13. ',' ',' 2. ',' 2',' 3',' 3. ',' 4. ',' 5 ',' 6. ');
for ($i=0; $i<10; $i++) {
$left=$Left_W[$i];
$right=$Right_W[$i];
if ($left<$right) $RO='<';
else $RO= '>';
echo "($i) '$left' $RO '$right'<br>";}
?>
结果是
(0) ' 12' < ' 12 '
(1) ' 13 ' < ' 13. '
(2) ' “4 ' > ' '
(3) ' 2 ' < ' 2. '
(4) ' 2. ' > ' 2'
(5) ' 3 ' > ' 3'
(6) ' 3 ' < ' 3. '
(7) ' 4 ' < ' 4. '
(8) ' 5. ' > ' 5 '
(9) ' 6 ' < ' 6. '
这点我同意然而,我使用的PHP认为'〈”在所有这些情况下都是正确的。
1条答案
按热度按时间dldeef671#
这只是部分答案:二分搜索的目的是在两种可能性之间进行下一次尝试。从0到16,第一个要看的地方是16。如果16是2的高,那么下一个要看的地方是8(0和16之间的一半)。代码$i=intval(($F+$L)/2);因为它是这样写的,会发现$i=intval((0+$15)/2)(=7)。这部分可以通过将公式更改为$i=intval(($F+$L+1)/2)来修复;这是一个微妙的错误,因为在B树被重新组织之前没有任何错误,之后重复的字符串可以很容易地添加到词树中。Word_tree是稀疏的,以允许其他条目。当单词树被重建时,已经添加的条目必须被放置在位置(顺序)中,二进制搜索将查找它们PS我不得不手工做算法来查找错误。