例如有:2001,2002,2003,3001,3002,3003,4008,4009,4010 
要求表示为:200[1-3]|300[1-3]|40[08-10]
该怎么做?
困扰了好多天。。求思路 求代码

解决方案 »

  1.   

    我自己的思路。。首先将连续的数放在一个数组中,如:
    $arr1=array(2001,2002,2003);
    $arr2=array(3001,3002,3003);
    $arr3=array(4008,4009,4010);
    然后找出每个数组中的最大数max和最小数min,按位比较max和min,找到相同部分与不相同部分,如:
    max=2003,min=2001 相同部分为200 不相同为3、1.
    再表示为200[1-3]问题是我不会写代码
      

  2.   

    我的思路比较笨,希望对楼主有帮助,有错误或者不完善的地方请楼主完善吧
    另外还考虑了有单个不连续的数字的情况,我在你的数组中间加了个'1030'
    -------------------------------------------------
    //此函数根据连续序列中结束的数字来查找最近的开头数字,返回相应格式的字符串
    //比如2003是结束数字,那么找到2001,返回:200[1-3]
    //$end_index是结束的那个数字在数组中的key值
    function get_str(&$arr,&$arr_sign,$end_index)
    {

    $str='';//存储相同的部分字符串
            $start='';//连续序列的最近的开始数字
    $end=$arr[$end_index];//连续序列中结束的数字

    //向回查找最近的start
    for($i=$end_index-1;$i>=0;$i--)
    {
    if($arr_sign[$i]=='start')
    {
    $start=$arr[$i];//连续序列的最近的开始数字
    break;
    }
    }
    //echo($start);
    for($i=0;$i<strlen($end);$i++)
    {
    if(substr($start, $i,1)==substr($end, $i,1))//把最后一个数字和第一个数字一位一位的比较,获得相同的部分
    {
    $str.=substr($start, $i,1);
    }
    else
    {
    break;
    }
    }
    $str2= substr($start, strlen($str));//开始的数字中不同的部分
    $str3= substr($end, strlen($str));//结束的数字中不同的部分
    return $str.'['.$str2.'-'.$str3.']';}
    $arr=array(2001,2002,2003,3001,3002,3003,1030,4008,4009,4010);
    $arr_sign=array();//上面数组对应的标记
    //1.start--开始
    //2.end--结尾
    //3.part--中间值
    //4.single--单个值,没有连续的
    $num_arr=count($arr);//数组长度
    if($num_arr==0)
    {
    exit('数组为空');
    }
    //如果数组只有一个数字就退出
    if($num_arr==1)
    {
    exit($arr[0]);
    }
    //获得数组中数字对应的标记
    for($i=0;$i<$num_arr;$i++)
    {
    if($i==0)//第一个数组元素只可能是start或者single
    {
    $arr_sign[$i]=($arr[$i+1]-$arr[$i]==1)?'start':'single';
    }
    else if($i==$num_arr-1)//最后一个数组元素,只可能是end或者single
    {
    $arr_sign[$i]=($arr[$i]-$arr[$i-1]==1)?'end':'single';
    }
    else//中间的数组元素,可能是start,part,end或者single
    {


    if($arr[$i]-$arr[$i-1]==1)//如果和前面的元素是相续的,那么此元素可能是part或者end
    {
    $arr_sign[$i]=($arr[$i+1]-$arr[$i]==1)?'part':'end';

    }
    else//如果和前面的元素不是相续的,那么此元素可能是single或者start
    {
    $arr_sign[$i]=($arr[$i+1]-$arr[$i]==1)?'start':'single';
    }

    }



    }
    //print_r($arr_sign);
    for($i=0;$i<$num_arr;$i++)
    {
    if($arr_sign[$i]=='end')
    {
    echo get_str($arr,$arr_sign,$i);
    if($arr_sign[$i+1]=='start'||$arr_sign[$i+1]=='single')
    {
    echo '|';
    }
    }
    else if($arr_sign[$i]=='single')
    {
    echo $arr[$i];
    if($arr_sign[$i+1]=='start'||$arr_sign[$i+1]=='single')
    {
    echo '|';
    }
    }


    }
      

  3.   

    本帖最后由 xuzuning 于 2011-10-09 10:58:47 编辑
      

  4.   


    $array = array(
    2001,2002,2003,3001,3002,3003,4008,4009,4010
    );function setMyRules($array,$length){
    $newArray = array();
    $outArray = array();
    $key = $minNum = $maxlength = $allLength = null;

    while(list($k,$v) = each($array)){
    $newNum = ($v/$length);
    $newArray[$newNum][] = $v%$length;
    }

    foreach($newArray as $k=>$v){
    $maxlength= strlen(max($v));
    $allLength = strlen($k*$length);
    $key = substr(($k*$length),0,($allLength - $maxlength));
    if(($maxlength>1) && ($maxlength < ($allLength-1))){
    $minNum = ("0"*$maxlength).min($v);
    }else{
    $minNum = min($v);
    }
    $outArray[]= $key."[".$minNum."-".max($v)."]";
    }

    return join("|",$outArray);
    }$newArray = setMyRules($array,1000);
    print_r($newArray);
    方法有很多,我的方法也比较笨。
      

  5.   


    我测试了一下是:2001,2002,2004显示 200[1-2]|2004 哦
    function get_str(&$arr,&$arr_sign,$end_index)
    { $str='';//存储相同的部分字符串
    $start='';//连续序列的最近的开始数字
    $end=$arr[$end_index];//连续序列中结束的数字 //向回查找最近的start
    for($i=$end_index-1;$i>=0;$i--)
    {
    if($arr_sign[$i]=='start')
    {
    $start=$arr[$i];//连续序列的最近的开始数字
    break;
    }
    }
    //echo($start);
    for($i=0;$i<strlen($end);$i++)
    {
    if(substr($start, $i,1)==substr($end, $i,1))//把最后一个数字和第一个数字一位一位的比较,获得相同的部分
    {
    $str.=substr($start, $i,1);
    }
    else
    {
    break;
    }
    }
    $str2= substr($start, strlen($str));//开始的数字中不同的部分
    $str3= substr($end, strlen($str));//结束的数字中不同的部分
    return $str.'['.$str2.'-'.$str3.']';}
    $arr=array(2001,2002,2004,);
    $arr_sign=array();//上面数组对应的标记
    //1.start--开始
    //2.end--结尾
    //3.part--中间值
    //4.single--单个值,没有连续的
    $num_arr=count($arr);//数组长度
    if($num_arr==0)
    {
    exit('数组为空');
    }
    //如果数组只有一个数字就退出
    if($num_arr==1)
    {
    exit($arr[0]);
    }
    //获得数组中数字对应的标记
    for($i=0;$i<$num_arr;$i++)
    {
    if($i==0)//第一个数组元素只可能是start或者single
    {
    $arr_sign[$i]=($arr[$i+1]-$arr[$i]==1)?'start':'single';
    }
    else if($i==$num_arr-1)//最后一个数组元素,只可能是end或者single
    {
    $arr_sign[$i]=($arr[$i]-$arr[$i-1]==1)?'end':'single';
    }
    else//中间的数组元素,可能是start,part,end或者single
    {
    if($arr[$i]-$arr[$i-1]==1)//如果和前面的元素是相续的,那么此元素可能是part或者end
    {
    $arr_sign[$i]=($arr[$i+1]-$arr[$i]==1)?'part':'end';
    }
    else//如果和前面的元素不是相续的,那么此元素可能是single或者start
    {
    $arr_sign[$i]=($arr[$i+1]-$arr[$i]==1)?'start':'single';
    } }}
    //print_r($arr_sign);
    for($i=0;$i<$num_arr;$i++)
    {
    if($arr_sign[$i]=='end')
    {
    echo get_str($arr,$arr_sign,$i);
    if($arr_sign[$i+1]=='start'||$arr_sign[$i+1]=='single')
    {
    echo '|';
    }
    }
    else if($arr_sign[$i]=='single')
    {
    echo $arr[$i];
    if($arr_sign[$i+1]=='start'||$arr_sign[$i+1]=='single')
    {
    echo '|';
    }
    }
    }