假设我在数组中有以下数字序列:
$numbers = array(1,3,2,23,24,25,26, 8)
如何在范围内打印它们,例如:
数字是1-3,23-26,8。
答案 0 :(得分:10)
这是一个简单的版本,创建包含范围的groups
<?php
$numbers = array(1,3,2,23,24,25,26,8);
sort($numbers);
$groups = array();
for($i = 0; $i < count($numbers); $i++)
{
if($i > 0 && ($numbers[$i - 1] == $numbers[$i] - 1))
array_push($groups[count($groups) - 1], $numbers[$i]);
else // First value or no match, create a new group
array_push($groups, array($numbers[$i]));
}
foreach($groups as $group)
{
if(count($group) == 1) // Single value
echo $group[0] . "\n";
else // Range of values, minimum in [0], maximum in [count($group) - 1]
echo $group[0] . " - " . $group[count($group) - 1] . "\n";
}
输出
1 - 3
8
23 - 26
现在,如果范围的顺序很重要,就像您在问题中所描述的那样,您仍然可以对您的组进行排序......从我所看到的,您希望范围首先跟随单个值吗?这可以通过添加
来完成function groupRanges($a, $b)
{
if(count($a) == 1)
if(count($b) == 1)
return 0; // equal
else
return 1; // so $b is considered less than
if(count($b) == 1)
return -1; // so $a is considered less than
return 0; // both are ranges, keep them there... could be adjusted to compare the size of each range
}
usort($groups, "groupRanges");
在foreach
之前,输出变为:
1 - 3
23 - 26
8
答案 1 :(得分:1)
$numbers = array(1,3,2,23,24,25,26,8);
$result = array();
$sorted = $numbers;
sort($sorted);
$current = null;
foreach ($sorted as $v) {
if (is_null($current)) {
$current = array($v, $v);
} else {
if ($current[1] + 1 == $v) {
$current[1] = $v;
} else {
$result[] = $current;
$current = array($v, $v);
}
}
}
$result[] = $current;
$arranged = array();
foreach ($numbers as $v) {
foreach ($result as $k => $r) {
if ($v >= $r[0] && $v <= $r[1]) {
$arranged[] = $r;
unset($result[$k]);
break;
}
}
}
var_dump($arranged);
答案 2 :(得分:1)
我知道我参加派对有点晚了,但我不得不这样做。
<?php
$numbers = array(1,3,2,23,24,25,26,8);
sort($numbers);
$x=0;
$output = array();
foreach($numbers as $k=>$n){
if(isset($numbers[$k+1]) && $numbers[$k+1]==$n+1){
$output[$x][]=$n;
}elseif(isset($output[$x][count($output[$x])-1]) && $output[$x][count($output[$x])-1]+1==$n){
$output[$x][]=$n;
}else{
$x++;
$output[$x][] = $n;
$x++;
}
}
foreach($output as $o){
echo $o[0];
if(isset($o[count($o)-1]) && $o[count($o)-1]!=$o[0]){
echo ' - '.$o[count($o)-1];
}
echo '<br>';
}?>
答案 3 :(得分:1)
昨天无法发布,所以我很迟。认为它很优雅,可以分享它。
<?php
$numbers = array(1, 3, 2, 23, 24, 25, 26, 8);
sort($numbers);
$result = array();
while (count($numbers) > 0)
{
$begin = reset($numbers);
$end = array_shift($numbers);
while (in_array($end + 1, $numbers))
{
$end = array_shift($numbers);
}
$beginAndEnd = array_unique(array($begin, $end));
$result[] = implode('-', $beginAndEnd);
}
var_dump($result);
?>
答案 4 :(得分:0)
首先对数组进行排序,比如数组A
。然后对它进行二进制搜索。
假设数组的大小为n
:
A[n/2]
,n/2
处的元素。
如果A[n/2]-A[n/4] = n/2-n/4
,那么
A[n/2]
和A[n/4]
位于同一群组中 - 跳过A[3n/8]
并查看A[n/8]
即可查看
是否A[n/2]-A[n/8] = n/2-n/8
。
如果A[n/2]-A[n/4] != n/2-n/4
,那么你手边有两个团体 - 一个团体
A[n/2]
in {和另一个A[n/4]
in。检查A[n/8]
以查看它是否在同一组中
A[n/4]
。检查A[3/8]
以查看它是否与A[n/2]
位于同一组中,如果不是,则是否
在A[n/4]
组中。
您也可以将它与排序算法结合使用,但我认为这不值得。这很快 - 在对数时间内是模块化的。
答案 5 :(得分:0)
$sorted = $numbers;
sort($sorted);
$sorted[] = null; # add a null so the last iteration stores the final range
$ranges = array();
$end = null;
$start = null;
foreach ($sorted as $x) {
if ($start === null) {
# first iteration. New range, but there's no previous one to mention
$start = $x;
}
elseif ($x !== $end + 1) {
# non-contiguous values == new range.
# squirrel away the one we were just working on, and start fresh
$ranges[] = ($start === $end) ? "$start" : "$start-$end";
$start = $x;
}
$end = $x;
}
$ranges_str = implode(', ', $ranges);
答案 6 :(得分:0)
function get_ranges($numbers) {
sort($numbers);
$ranges=array();
while(current($numbers)){
$start=current($numbers);
$next=next($numbers);
$current=$start;
while( ($next-$current)==1){
$current=$next;
$next=next($numbers);
}
$ranges[]=array('start'=>$start,'end'=>$current);
}
return $ranges;
}