我如何识别“群体”?数组中连续数字的数目(PHP)


How can I identify "groups" of sequential numbers in an array (PHP)?

我一直在寻找这个问题的答案。到目前为止,我找到的所有东西都接近我需要的,但不完全是。我就是找不到合适的关键词组合来搜索。

我有一个定义了缺少键的数组,像这样(键是自动从其他数据生成的,可以是任何东西,尽管它们总是按从低到高的顺序排列):

$Array = array(
    1 => "A",
    2 => "B",
    4 => "C",
    7 => "D",
    8 => "E",
    9 => "F",
    12 => "G",
    15 => "H",
    16 => "I"
);

我需要创建另一个数组来检测每组按顺序编号的键,如下所示:

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 2
        )
    [1] => Array
        (
            [0] => 7
            [1] => 8
            [2] => 9
        )
    [2] => Array
        (
            [0] => 15
            [1] => 16
        )
)

键"4"answers"12"将被丢弃,因为"5"answers"13"分别不存在。

我怎样才能做到这一点?

我已经尝试了我能想到的for、foreach和while循环迭代的所有组合。我总是得到完全混乱的,过长的数组,看起来像

[ . . . ]
[16] => Array
    (
        [0] => 7
        [1] => 8
        [2] => 9
    )
[19] => Array
    (
        [0] => 4
    )
[21] => Array
    (
        [0] => 7
        [1] => 8
        [2] => 9
    )
[27] => Array
    (
        [0] => 8
        [1] => 9
    )
[30] => Array
    (
        [0] => 9
    )
[33] => Array
    (
        [0] => 8
        [1] => 9
    )
[ . . . ]

我在想一个更好的方法,但这是有效的:

$i = 0;
foreach($Array as $k => $v) {
    if(isset($Array[$k+1])) {
        $result[$i][] = $k;
        $result[$i][] = $k+1;
        $result[$i] = array_unique($result[$i]);
    } else {
        $i++;
    }
}

粘合在一起,但需要进一步测试:

$Array = array(
    1 => "A",
    2 => "B",
    4 => "C",
    7 => "D",
    8 => "E",
    9 => "F",
    12 => "G",
    15 => "H",
    16 => "I"
);
$ret = array();
$cur = array();

print_r($Array);
$prevKey = NULL;
foreach($Array as $k => $v)
{
    if (!isset($prevKey) || $k - $prevKey == 1)
    {
        $cur[] = $k;
    } else {
        $ret[] = $cur;
        $cur = array();
        $cur[] = $k;
    }
        $prevKey = $k;
}
if (count($cur) > 0)
    $ret[] = $cur;
print_r($ret);
输出:

Array
(
    [1] => A
    [2] => B
    [4] => C
    [7] => D
    [8] => E
    [9] => F
    [12] => G
    [15] => H
    [16] => I
)
Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 2
        )
    [1] => Array
        (
            [0] => 4
        )
    [2] => Array
        (
            [0] => 7
            [1] => 8
            [2] => 9
        )
    [3] => Array
        (
            [0] => 12
        )
    [4] => Array
        (
            [0] => 15
            [1] => 16
        )
)

这是特定的有一个现有的PHP函数。这应该按照您指定的方式生成结果…

$Array = array(
    1 => "A",
    2 => "B",
    4 => "C",
    7 => "D",
    8 => "E",
    9 => "F",
    12 => "G",
    15 => "H",
    16 => "I"
);
$lastNum = -1;
$sequences = array();
$curSequence = array();
foreach($Array as $arrayIndex => $arrayValue){
    if($arrayIndex == $lastNum + 1 || $lastNum === -1){
        //Is sequential...
        $curSequence[] = $arrayIndex;
    }else{
        //Non-sequential...
        if(count($curSequence) > 1){
            //Add current sequence
            $sequences[] = $curSequence;
        }
        //Start a new sequence
        $curSequence = array($arrayIndex);
    }
    $lastNum = $arrayIndex;
}
//At the end of the loop, store current sequence
if(count($curSequence) > 1){
    $sequences[] = $curSequence;
}
echo "<pre>"; print_r($sequences); echo "</pre>";
结果

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 2
        )
    [1] => Array
        (
            [0] => 7
            [1] => 8
            [2] => 9
        )
    [2] => Array
        (
            [0] => 15
            [1] => 16
        )
)

问题标记为PHP但如果有人感兴趣,这里有一个Java解决方案

import java.util.*;

public class FindSequential {
public static void main(String args[]) {
    Map<Integer, String> inputMap = new LinkedHashMap<Integer, String>();
    inputMap.put(1,"A");
    inputMap.put(2,"B");
    inputMap.put(4,"C");
    inputMap.put(5,"D");
    inputMap.put(8,"E");
    inputMap.put(9,"F");
    inputMap.put(12,"G");
    inputMap.put(15,"H");
    inputMap.put(16,"I");
    inputMap.put(18,"J");
    inputMap.put(20,"K");
    inputMap.put(21,"L");
    Map<Integer, List<Integer>> outputList = new HashMap<Integer, List<Integer>>();
    int previousKey = -1;
    int outputListIndex = 0;
    List<Integer> tempList = null;
    for (int key: inputMap.keySet()) {
        if(previousKey == -1) {
            // first element
            previousKey = key;
            tempList = new ArrayList<Integer>();
            continue;
        }
        int diff = key - previousKey;
        if(diff == 1) {
            // continuous sequence
            if(!tempList.contains(previousKey)) {
                tempList.add(previousKey);
            }
            if(!tempList.contains(key)) {
                tempList.add(key);
            }
            outputList.put(outputListIndex,tempList);
        } else {
            // not a sequence
            if(tempList.size() > 0) {
                outputListIndex++;
            }
            tempList = new ArrayList<Integer>();
        }
        previousKey = key;
    }
    // you can print the outputList here
  }
}