0

假设我有一个数字,比如说 5。现在假设有 5 个成员。现在每个成员开始从1数到2。那些获得第二个数字的成员离开然后重新计数从下一个成员开始。所以最后在这种情况下,第三个成员最后留下了。

所以我试着像这样实现。首先将成员分配为数组 $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 个成员)离开了。
我想打印最后一个离开的成员。

我怎样才能做到这一点?

我你看不懂然后看看这个 生存策略

4

5 回答 5

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];
于 2013-03-22T15:13:26.360 回答
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";
}
于 2013-03-25T20:01:10.077 回答
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 as $key=>$value) { ...选择最大值等... }

于 2013-03-22T14:59:37.263 回答
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 开始

于 2013-03-22T15:20:49.617 回答
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";
于 2013-03-25T18:53:04.253 回答