从数组中生成字符串范围(1-10,13,16,17-25 ..等)的算法

时间:2014-04-11 11:06:26

标签: php algorithm

我正在尝试计算出数组中存在的页码范围。我确实试图搜索谷歌,但我只发现了不相关的帖子/页面。

我一直在研究的代码是:

$numbers = array(1,3,2,4,5,6,7,8,9,11,10,15,14,13,12,16,17,18,19,20,22);

function get_number_ranges($numbers)
{
    $last = null;
    foreach ($numbers as $number) {
        if (is_null($last)) {
            $string = $number;
            $last = $number;
        } elseif ($last + 1 != $number) {
            $string .= '-' . $last . ', ' . $number;
            $last = $number;
        } else {
            $last = $number;
        }
    }

    if ($last == $number) {
        $string .= '-' . $number;
    }

    return $string;
}

并产生

1-1, 3-3, 2-2, 4-9, 11-11, 10-10, 15-15, 14-14, 13-13, 12-12, 16-20, 22-22

我不希望它显示重复的数字,所以我希望它看起来像这样:

1, 3, 2, 4-9, 11, 10, 15, 14, 13, 12, 16-20, 22

这样我就可以在存储文档历史时表示页面范围。

我相信对于某些人来说这将是一个很好的方便,任何帮助都将受到极大的欢迎!

3 个答案:

答案 0 :(得分:2)

基本上你需要记住每个范围的第一个数字,当你来附加连字符和最后一个数字时,只有在最后一个数字不同时才这样做。像(未经测试)的东西:

function get_number_ranges($numbers)
{
    $last = null;
    foreach ($numbers as $number) {
        if (is_null($last)) {
            $string = $number;
            $last = $number;
            $first = $number ;                          //Remember first
        } elseif ($last + 1 != $number) {
            if ($first != $last )                       //Only append if different
                $string .= '-' . $last ;
            $string .= ', ' . $number;
            $last = $number;
            $first = $number ;                          //Remember first
        } else {
            $last = $number;
        }
    }

    if ($last == $number && $last != $first) {          //Only if different
        $string .= '-' . $number;
    }

    return $string;
}

答案 1 :(得分:1)

添加变量以保存范围的第一个数字。如果最后一个数字等于第一个数字,那么它不是一个范围,不需要'-XX'。

$numbers = array(1,3,2,4,5,6,7,8,9,11,10,15,14,13,12,16,17,18,19,20,22);

function get_number_ranges($numbers)
{
    $last = null;
    $firstFromRange = null;
    foreach ($numbers as $number) {
        if (is_null($last)) {
            $string = $number;
            $firstFromRange = $number; // new range begins, save the number
        } elseif ($last + 1 != $number) {
            if ($firstFromRange == $last) { // if the range is only one number, don't add '-' . $last
                $string .= ', ' . $number;
            } else {
                $string .= '-' . $last . ', ' . $number;
            }
            $firstFromRange = $number; // new range begins, save the number
        }

        $last = $number;
    }

    if ($last == $number && $last != $firstFromRange) {
        $string .= '-' . $number;
    }

    return $string;
}

答案 2 :(得分:0)

我认为你在找这样的东西

<?php
$numbers = array(1,3,2,4,5,6,7,8,9,11,10,15,14,13,12,16,17,18,19,20,22);

function get_number_ranges($numbers){
    $result = '';
    if( is_array($numbers) ){
        $start = $end = array_shift($numbers);
        for($i=0,$c=count($numbers);$i<$c;$i++){
            if($end == $numbers[$i]-1){
                $end = $numbers[$i];
            }else{
                $result .= ($start == $end) ? $start: $start.'-'.$end;
                $result .= ',';
                $start = $end = $numbers[$i];
            }
        }
        $result .= ($start == $end) ? $start: $start.'-'.$end;
    }

    return $result;
}

echo get_number_ranges($numbers );

请参阅键盘结果http://codepad.org/l1JUSVJO