如何判断逗号分隔的数字列表是否符合数字的自然顺序

时间:2014-12-01 15:51:09

标签: php

我有一个逗号分隔的数字列表,我将其转换为数组,我想知道的数字列表是否列出的数字遵循数字的自然顺序,你知道,确切地说有{ {1}}在下一个和上一个之间。

如果它的真实,列表服从自然顺序,我想选择列表的第一个数字,如果不是,列表不服从自然顺序,我选择第二个。

这是我的代码。

1

我遇到的问题是弄清楚如何测试所有数组元素的差异。

4 个答案:

答案 0 :(得分:0)

尝试使用函数来解决这个问题......就像这样:

<?php
error_reporting(0);
/**
Analyze numbers

Condition 1

if from number to the next has a difference of 1,then pick the first number in the list

Condition 2

if from one number the next,a difference of greater than 1 was found,then pick next from first

Condition 3

if list contains only one number,pick the number
*/
$number_picked = null;

$a = '5,7,8,9,10';
$b = '2,3,4,5,6,7,8,9,10';
$c = '10';

function test($string) {    
    $data = explode(',', $string);
    if(count($data) === 1){
        return 'number is:'.$number;
    }

    foreach($data as $index => $number)
    {

        $previous = $data[($count+$index-1) % $count]; 

        $current = $number;
        $next = $data[($index+1) % $count];

        $diff = ($next - $previous);

        if($diff == 1){
            $number_picked = array_values($data)[0];
            return $number_picked.'correct';
        }
        elseif($diff > 1){
            $number_picked = array_values($data)[1];
            return $number_picked.'wrong';
        }
    }
}

echo test($a);
echo test($b);
echo test($c);
?>

答案 1 :(得分:0)

你已经知道如何爆炸列表,所以我会跳过它。 你已经处理了一个项目,所以我也会跳过它。

剩下的就是检查阵列的其余部分。基本上;有两个可能的结果值:第一个元素或第二个元素。所以我们先保存这两个:

$outcome1 = $list[0];
$outcome2 = $list[1];

接下来,我们将循环遍历这些项目。我们将记住最后找到的项目,并确保新旧项目之间的区别为1.如果是,我们继续。如果不是,我们会中止并立即返回$ outcome2。

如果我们在不中止的情况下到达列表的末尾,它会自然排序,所以我们返回$ outcome1。

$lastNumber = null;
foreach( $items as $number ) {
  if($lastNumber === null || $number - $lastNumber == 1 ) {
    // continue scanning
    $lastNumber = $number;
  }
  else {
    // not ordened
    return $outcome2;
  }
}
return $outcome1; // scanned everything; was ordened.

(注意:代码未经测试)

答案 2 :(得分:0)

为了避免访问上一个或下一个元素的头痛,并决定它是否仍然在数组内部,请使用以自然顺序项目i和第一个项目具有i的差异的事实。

你调用条件3的角落情况也比循环内部更容易处理。但更容易的是,我们描述自然有序列表的方式适用于单项列表:

$natural = true;
for($i=1; $i<$count && $natural; $i++)
    $natural &= ($data[$i] == $data[0] + $i)

$number = $natural ? $data[0] : $data[1];

对于$count == 1,永远不会输入循环,因此$natural会保留true:您选择第一个元素。

答案 3 :(得分:0)

不需要循环,maths会在这里帮助你。将数字放入数组后:

$a = explode(',', '5,7,8,9,10');

将它们传递给这个函数: -

function isSequential(array $sequence, $diff = 1)
{
    return $sequence[count($sequence) - 1] === $sequence[0] + ($diff * (count($sequence) - 1));
}

如果数组中的数字遵循自然序列,则该函数将返回true。您甚至应该能够使用$ diff参数调整数字之间的不同间距,例如2, 4, 6, 8等,尽管我没有彻底tested that

See it working

请注意,只有在您的号码列表从最小到最大排序时才会有效。