使用 SplQueue 无限循环

Infinite loop with SplQueue

我需要一个队列,我可以在队列中添加对象(先进先出)。 此外,我跟踪哈希图中没有重复的对象。

<?php

$test = new \SplQueue();
$done = array();

// Put 'test a' in queue
$test->enqueue('test a');

// While we have objects in the queue...
while ($test->valid()) {
    // Echo the current object
    $current = $test->current();
    echo $current, PHP_EOL;

    // Remove the current object and add it to "done"
    $test->dequeue();
    $done[$current] = 1;

    // Add more to queue
    $new = array('test a', 'test b', 'test c');
    foreach ($new as $newObject) {
        if (! isset($done[$newObject])) {
            $test->enqueue($newObject);
        }
    }
}

在 PHP 键盘上,我没有得到任何结果。 怎么了?

更新:一段时间后我得到输出:

test a 
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /code/NIPg42 on line 25
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /code/NIPg42 on line 25

我对已经完成的对象进行出队和测试,为什么这是一个无限循环?

第 25 行是 $test->enqueue($newObject);

对我来说,使用 SplQueue 更容易(也更自然),使用两种基本方法 enqueue 将项目放在末尾队列的 dequeue 以从队列的开头提取您必须处理的项目。这意味着摆脱 current,使用 dequeue 结果 代替:

$current = $test->dequeue();
$done[$current] = 1;
var_dump($current); // or any other processing

由于尝试使空列表出列会导致错误,因此您必须先进行检查。所以你的代码变得类似于这样:

$test = new \SplQueue();
$done = array();

// Put 'test a' in queue
$test->enqueue('test a');

// While we have objects in the queue...
while (!$test->isEmpty()) {
    $item = $test->dequeue();
    $done[$item] = 1;
    var_dump($item); 

    // Add more to queue
    $new = array('test a', 'test b', 'test c');
    foreach ($new as $newObject) {
        if (! isset($done[$newObject])) {
            $test->enqueue($newObject);

// without this line, `test c` will be enqueued twice.
            $done[$newObject] = 1; 
        }
    }
}

Demo。如您所见,这里还有另一个变化:在执行 enqueue 之前设置哈希。如果您确实想制作一个 HashQueue(某种),我建议您制作自己的 class(扩展或使用 SplQueue);密钥将伴随每个 enqueue 操作和相应的 check/addition 进行散列。