2013-03-22 113 views
0

假設我有一個數字讓我們說5現在讓我們假設有5個成員。現在每個成員開始計算1到2.那些獲得第二個數字的成員離開,然後再次計數從下一個成員開始。所以最後在這種情況下,第三位成員最後停留。如何在PHP中循環遍歷數組的循環?

所以我試圖實現這樣的。首先將數組賦值爲數組$ v。

for($i=1 ; $i<=5 ; $i++) 
{ 
    $v[] = $i; 
} 

$v1 = array_flip($v); 

for($i=0 ; $i<=5 ; $i += 2) 
{ 
    unset($v1[$i]); 
} 

echo "<pre>"; 
print_r($v1); 

輸出

Array 
(
    [1] => 0 
    [3] => 2 
    [5] => 4 
) 

現在我想從計數鍵5(5件)的數字再次1(1件)等。

所以最後鍵3(第3個成員)離開。
我想打印最後一個成員。

我該如何做到這一點?

我就無法理解,然後看這個 Survival Strategy

+0

聽起來像你需要刪除陣列開始的元素,並把它們放在最後?並重置內部指針以重新開始?你可以使用'array_slice()'和'array_push()'來做到這一點 – Waygood 2013-03-22 14:46:54

+0

@Waygood兄看到上面的數組假設在最後一次迭代指針是在第五關鍵我想計算第五個鍵本身爲1並再次從第一個鍵開始作爲計數否2。所以第一個鍵將被刪除。所以現在只有鑰匙3和5離開了。現在鍵3作爲一個鍵,鍵5作爲2,所以現在鍵5被移除。 – 2013-03-22 14:58:39

+2

我讀了四次關於你的問題,但仍然很難弄清楚你想達到什麼目的。你能編輯你的問題,並試圖更清楚地解釋你想達到的目標嗎?例如5個成員和5個巧合,或者它們是相關的? '$ num'從哪裏來?這是你之前談到的數字嗎?什麼是確切的最終目標?如果你能爲我解決這個問題,那會很棒。 – 2013-03-22 14:59:54

回答

1

下面是一個面向對象的解決方案,帶有一個易於使用的reduce方法和多個示例。

class CountByTwoArrayReducer { 

    public function __construct($array) { 
    $this->array = $array; 
    $this->size = count($array); 
    } 

    public function reduce() { 
    $this->initialize(); 

    while($this->hasMultipleItems()) { 
     $this->next(); 
     $this->removeCurrentItem(); 
     $this->next(); 
    } 

    return $this->finalItem(); 
    } 

    protected function initialize() { 
    $this->current = 1; 
    $this->removed = array(); 
    $this->remaining = $this->size; 
    } 

    protected function hasMultipleItems() { 
    return ($this->remaining > 1); 
    } 

    protected function next($start = null) { 
    $next = ($start === null) ? $this->current : $start; 

    do { 
     $next++; 
    } while(isset($this->removed[$next])); 

    if($next > $this->size) 
     $this->next(0); 
    else 
     $this->current = $next; 
    } 

    protected function removeCurrentItem() { 
    $this->removed[$this->current] = 1; 
    $this->remaining--; 
    } 

    protected function finalItem() { 
    return $this->array[$this->current - 1]; 
    } 

} 

$examples = array(
    array('A', 'B', 'C', 'D', 'E'), 
    range(1, 100), 
    range(1, 1000), 
    range(1, 10000) 
); 

foreach($examples as $example) { 
    $start = microtime(true); 

    $reducer = new CountByTwoArrayReducer($example); 
    $result = $reducer->reduce(); 

    $time = microtime(true) - $start; 

    echo "Found {$result} in {$time} seconds.\n"; 
} 
0

嗯,我可以推薦兩個功能:

  1. http://php.net/manual/en/function.array-keys.php

    這將重新索引您陣列,索引:0,1,2

  2. http://php.net/manual/en/control-structures.foreach.php

    有了這個,你可以通過辦理任何數組:

    的foreach($ V1爲$鍵=> $值){...選擇最大,等...}

+0

考慮添加相關的代碼,而不是僅僅鏈接到另一個頁面。如果這些鏈接破裂,你的答案將不會真正幫助未來的訪問者。 – MikeSmithDev 2013-03-22 15:25:16

1

這將刪除陣列中的所有其他項目,直到只剩下單個項目。

$members = range(1, 5); 

$i = 0; 

while(count($members) > 1) { 
$i++; 
if($i == count($members)) $i = 0; 
unset($members[$i]); 
$members = array_values($members); 
if($i == count($members)) $i = 0; 
} 

echo $members[0]; 
+0

Thanx代碼。欣賞它。但是,如果我將範圍設置爲大於10000,那麼它將超出執行時間並進入無限循環。我想要超過10個範圍的範圍。如果代碼在不到2秒的時間內運行,它也會更好。 thanx再次。 – 2013-03-23 10:01:15

+0

這不是一個無限循環。在這麼大的範圍內需要更長的時間。我會發布另一個更高效的解決方案。 – psparrow 2013-03-25 17:58:50

+0

此解決方案(http://stackoverflow.com/a/15623672/673079)可以在大約1秒內處理100,000個項目。 – psparrow 2013-03-25 20:06:18

0
<?php 

function build_thieves($thieves) 
{ 
    return range(1, $thieves); 
} 

function kill_thief(&$cave) 
{ 
    if(sizeof($cave)==1) 
    { 
     $thief=array_slice($cave, 0, 1); 
     echo $thief.' survived'; 
     return false; 
    } 

    $thief=array_slice($cave, 0, 1); 
    array_push($cave, $thief); 

    $thief=array_slice($cave, 0, 1); 
    echo $thief.' killed'; 
    return true; 
} 

$cave=build_thieves(5); 
$got_data=true; 
while($got_data) 
{ 
    $got_data=kill_thief($cave); 
} 

調整到每2,而不是每3。並從1開始不是0

0

這個答案有點複雜,但它更有效率。它不會創建一個項目的數組,然後將其刪除。它從一個值開始(例如1)並計算下一個還沒有被移除的項目。然後,它將其標記爲已刪除。如果您實際上有一組項目,則最終項目的索引將爲$ current - 1.下面的示例使用值1到10,000。在我的機器上,它只需要超過0.05秒。

define('SIZE', 10000); 

/** 
* Helper function to return the next value 
*/ 
function get_next($current, &$removed) { 
    $next = $current; 
    do { 
    $next++; 
    } while(isset($removed[$next])); 

    return ($next > SIZE) ? get_next(0, $removed) : $next; 
} 

$current = 1; 
$removed = array(); 
$remaining = SIZE; 

$start_time = microtime(true); 

while($remaining > 1) { 
    $current   = get_next($current, $removed); 
    $removed[$current] = 1; 
    $remaining   = SIZE - count($removed); 
    $current   = get_next($current, $removed); 
} 

$total_time = microtime(true) - $start_time; 

echo "Processed " . SIZE . " items\n"; 
echo "Winning item: {$current}\n"; 
echo "Total time: {$total_time} seconds\n";