PHP リンク リスト、ローダー モード、およびコール エントリ保護
これはとても興味深い質問です。三人が出会うとき、奇妙な衝突が起こる。
ローダー モードがリンク リストのさまざまな操作のアルゴリズムを実装する場合、$this を使用してリンク リスト自体をリンク リストに渡します。そのため、アルゴリズム上、リンクリストの先頭を削除することはできません。
具体的なパフォーマンスは、関数内でヘッドが正常に削除され、戻り値が元のヘッドとして記憶されることです。
なぜですか?玄関保護に電話したことがトラブルを引き起こしていることが判明。しかし、よく考えてみると、この保護は必要です。それ以外の場合、関数フローには戻る場所がありません。これ以上続けることはできません。
したがって、アルゴリズムは頭部を削除するという考えを放棄することしかできません。これを達成するにはどうすればよいでしょうか?次のコードを見てください:
<?php error_reporting(E_ALL); class csList{ public $data=''; public $parent; ??????? public $childNodes=array(); public function __construct($data=false){ $this->data=$data; } //问题就是出在这里,因为这里是调用入口,本节点自然不可以被删除。 public function loadData($dataString,$className){ $obj=new $className(); $obj->loadDataString($dataString,$this); //print_r($this); //这里是错的。 } } class csStringAdapter{ public function loadDataString($dataString, csList $cl, $level=0){ $spliter=array("\r\n", ',',' '); $dataArray=explode($spliter[$level],$dataString); for($i=0,$j=count($dataArray);$i<$j;$i++){ $newNode=new csList(); $newNode->parent = $cl; $cl->childNodes[]=$newNode; $dataItems=explode(' ', $dataArray[$i]); if (strpos($dataArray[$i],$spliter[$level+1])!==false){ echo 1;// exit; $this->loadDataString($dataArray[$i],$newNode,$level+1); }else{ $newNode->data=$dataArray[$i]; } } if ((count($cl->childNodes)==1) && ($cl->data=='')){ //因为head节点是空节点,所以要删除 $cl=$cl->childNodes[0];//这样删除head是不行的。 //print_r ($cl); //但这里打印输出的结果是正确的。 } } } $test = new csList(); $nodeStr='a,b,c,d,e'; $test->loadData($nodeStr,'csStringAdapter'); print_r($test); //这里打印也是错的。head总是空节点,即是无data,同时只有一个childNodes的节点 ?>
?
PHP による呼び出しエントリの保護、つまりプログラム内の関数呼び出しがどこから来てどこに戻る必要があるのかを理解すると、上記のコードを変更できます。以下は修正コードです
<?php error_reporting(E_ALL); class csList{ public $data=''; public $parent; public $childNodes=array(); public function __construct($data=false){ $this->data=$data; } //问题就是出在这里,因为这里是调用入口,本节点自然不可以被删除。 public function loadData($dataString,$className){ $obj=new $className(); $obj->loadDataString($dataString,$this); //print_r($this); //这里是对的。 } } class csStringAdapter{ public function loadDataString($dataString, csList $cl, $level=0){ $spliter=array("\r\n", ',',' '); $dataArray=explode($spliter[$level],$dataString); for($i=0,$j=count($dataArray);$i<$j;$i++){ $newNode=new csList(); $newNode->parent = $cl; $cl->childNodes[]=$newNode; $dataItems=explode(' ', $dataArray[$i]); if (strpos($dataArray[$i],$spliter[$level+1])!==false){ echo 1;// exit; $this->loadDataString($dataArray[$i],$newNode,$level+1); }else{ $newNode->data=$dataArray[$i]; } } if ((count($cl->childNodes)==1) && ($cl->data=='')){ //因为head节点是空节点,所以要删除 //$cl=$cl->childNodes[0];//这样删除head是不行的。 //print_r ($cl); //但这里打印输出的结果是正确的。 //我们这样修改:将子节点数据复制到父节点中,实际是放弃第一层子节点: $cl->data=$cl->childNodes[0]->data; $cl->childNodes=$cl->childNodes[0]->childNodes; for($i=0,$j=count($cl->childNodes);$i<$j;$i++){ $cl->childNodes[$i]->parent=$cl; } } } } $test = new csList(); $nodeStr='a,b,c,d,e'; $test->loadData($nodeStr,'csStringAdapter'); print_r($test); //经过这样修改,一切就正确了。 ?>
?
?