PHP循环以检查一组数字是否连续

3

我正在尝试循环遍历一组记录,所有记录都有一个“number”属性。我想检查是否有3个连续的记录,例如6、7和8。

我认为下面的代码已经接近成功了,但在最后阶段遇到了困难 - 任何帮助都将是极好的!

$nums = array();
while (count($nums <= 3))
{
    //run through entries (already in descending order by 'number'
    foreach ($entries as $e)
    {
        //ignore if the number is already in the array, as duplicate numbers may exist
        if (in_array($e->number, $num))
            continue;
        else
        {
            //store this number in the array
            $num[] = $e->number;
        }
    //here i need to somehow check that the numbers stored are consecutive
    }
}
9个回答

2
function isConsecutive($array) {
    return ((int)max($array)-(int)min($array) == (count($array)-1));
}

您也可以不使用循环来达到相同的结果。


2
isConsecutive([1,3,0,0])现在返回什么? - miken32
如上所述。这并不像你期望的那样运作。 - Harry B

1
$arr = Array(1,2,3,4,5,6,7,343,6543,234,23432,100,101,102,103,200,201,202,203,204);

for($i=0;$i<sizeof($arr);$i++)
{ 
    if(isset($arr[$i+1]))
    if($arr[$i]+1==$arr[$i+1])
    {

        if(isset($arr[$i+2]))
        if($arr[$i]+2==$arr[$i+2]) 
        {

            if(isset($arr[$i+3]))       
            if($arr[$i]+3==$arr[$i+3])
            { 
                echo 'I found it:',$arr[$i],'|',$arr[$i+1],'|',$arr[$i+2],'|',$arr[$i+3],'<br>'; 
            }//if3

        }//if 2

    }//if 1
}

我还没有彻底调查过,也许可以改进以使其更快!


1
这将确认数组的所有项是连续的,要么向上,要么向下。
如果需要方向,则可以更新以返回一个 [$up,$down] 数组或另一个值。
function areAllConsecutive($sequence)
{
    $up = true;
    $down = true;
    foreach($sequence as $key => $item)
    {
        if($key > 0){
            if(($item-1) != $prev) $up = false;
            if(($item+1) != $prev) $down = false;
        }
        $prev = $item;
    }

    return $up || $down;
}

// areAllConsecutive([3,4,5,6]); // true
// areAllConsecutive([3,5,6,7]); // false
// areAllConsecutive([12,11,10,9]); // true

1
如果它们只需要连续,存储一个$last,并检查 $current == $last + 1。
如果你要找到 n 个连续的数字,使用相同的方法,但同时保持一个计数器来记录满足该要求的数字个数。

0
function isConsecutive($array, $total_consecutive = 3, $consecutive_count = 1, $offset = 0) {
    // if you run out of space, e.g. not enough array values left to full fill the required # of consecutive count
    if ( $offset + ($total_consecutive - $consecutive_count ) > count($array) ) {
        return false;
    }

    if ( $array[$offset] + 1 == $array[$offset + 1]) {
        $consecutive_count+=1;
        if ( $consecutive_count == $total_consecutive ) {
            return true;
        }
        return isConsecutive($array, $total_consecutive, $consecutive_count, $offset+=1 );
    } else {
        return isConsecutive($array, $total_consecutive, 1, $offset+=1 );
    }
}

0

这里有一个示例,可以检查任何大小的列表是否符合此要求:

class MockNumber
{
    public $number;
    public function __construct($number)
    {
        $this->number = $number;
    }

    static public function IsListConsecutive(array $list)
    {
        $result = true;
        foreach($list as $n)
        {
            if (isset($n_minus_one) && $n->number !== $n_minus_one->number + 1)
            {
                $result = false;
                break;
            }

            $n_minus_one = $n;
        }

        return $result;
    }
}

$list_consecutive = array(
     new MockNumber(0)
    ,new MockNumber(1)
    ,new MockNumber(2)
    ,new MockNumber(3)
);

$list_not_consecutive = array(
     new MockNumber(5)
    ,new MockNumber(1)
    ,new MockNumber(3)
    ,new MockNumber(2)
);

printf("list_consecutive %s consecutive\n", MockNumber::IsListConsecutive($list_consecutive) ? 'is' : 'is not');
// output: list_consecutive is consecutive

printf("list_not_consecutive %s consecutive\n", MockNumber::IsListConsecutive($list_not_consecutive) ? 'is' : 'is not');
// output: list_not_consecutive is not consecutive

0

我认为你需要类似于以下函数的东西(不需要数组来存储数据)

<?php
function seqOfthree($entries) {
// entries has to be sorted descending on $e->number
  $sequence = 0;
  $lastNumber = 0;

  foreach($entries as $e) {
    if ($sequence==0 or ($e->number==$lastNumber-1)) {
      $sequence--;
    } else {
      $sequence=1;
    }
    $lastNumber = $e->number;
    if ($sequence ==3) {
      // if you need the array of sequence you can obtain it easy
      // return $records = range($lastNumber,$lastNumber+2);
      return true;
    }
  }
  // there isn't a sequence
  return false;
}

嗨Eineki,条目是按降序排列的,你会如何修改你的代码以适应这种情况? - pauld78
@pauld78 只需将加号改为减号(我已经修改了函数来实现这一点) - Eineki

0

如果您不想涉及任何排序,选择任何三个连续的数字应该会给您: - 它要么毗邻另外两个数字(diff1 = 1,diff2 = -1) - 毗邻唯一的数字(diff = + -1)应符合上述语句。

测试第一个条件。如果失败,测试第二个条件并在成功时获得您的序列;否则集合不符合要求。

对我来说看起来是正确的。希望能有所帮助。


-1

下面的函数将返回连续元素的第一个索引,如果不存在则返回 false:

function findConsecutive(array $numbers)
{
    for ($i = 0, $max = count($numbers) - 2; $i < $max; ++$i)
        if ($numbers[$i] == $numbers[$i + 1] - 1 && $numbers[$i] == $numbers[$i + 2] - 2)
            return $i;
    return false;
}

编辑:这似乎引起了一些混淆。像{{link1:strpos()}}一样,如果存在任何元素,则此函数将返回其位置。该位置可能为0,可以评估为false。如果您只需要查看它们是否存在,则可以将return $i;替换为return true;。如果需要,您还可以轻松地使其返回实际元素。

编辑2:修复以实际查找连续数字。


我认为这个函数在 findConsecutive(array(1,5,9123)); 的情况下会失败。 - Frank Farmer
@Frank Farmer 它是怎么失败的?它返回 int(0),这是连续三个元素的第一个元素的索引。请注意,0 !== false。 - Daniel Egeberg
1、5和9123不是连续的。 - Frank Farmer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接