0

给定 PHP 中的元素数组,我希望创建一个新的二维数组,其中仅包含特定长度的幂集元素。例如,对于以下数组:

array(4) {
    0 => 'A',
    1 => 'B',
    2 => 'C',
    3 => 'D'
}

如果我要运行该函数,fixed_length_power_set( $arr, 2 )那么我希望它返回:

array(6) {
    0 => array(2) {
        0 => 'A',
        1 => 'B'
    }
    1 => array(2) {
        0 => 'A',
        1 => 'C'
    }

    2 => array(2) {
        0 => 'A',
        1 => 'D'
    }
    3 => array(2) {
        0 => 'B',
        1 => 'C'
    }
    4 => array(2) {
        0 => 'B',
        1 => 'D'
    }
    5 => array(2) {
        0 => 'C',
        1 => 'D'
    }
}

虽然我可以想出一些规则来概括这个过程,但由于某种原因,我似乎无法将其转化为代码。有人有建议吗?

4

2 回答 2

4

使用简单的递归算法:对于一组 size 的所有 size 子集的k集合n

  • 如果n == k,返回一个包含整个集合的集合;

  • 如果k == 1返回所有单例的集合;

  • 否则从集合中删除一个元素x:现在您需要k-1剩余集合的所有大小子集(即包含 的那些子集x),以及k剩余集合的所有大小子集(不包括的那些x)。

在 PHP 伪代码中:

function subsets_n($arr, $k)
{
  if (count($arr) < $k) return array();
  if (count($arr) == $k) return array(0 => $arr);

  $x = array_pop($arr);
  if (is_null($x)) return array();

  return array_merge(subsets_n($arr, $k),
                     merge_into_each($x, subsets_n($arr, $k-1)) );
}

这里merge_into_each()添加x到集合中的每个数组:

function merge_into_each($x, $arr)
{
  foreach ($arr as &$a) array_push($a, $x);
  return $arr;
}
于 2011-09-06T23:52:24.780 回答
0

我不是 PHP 专家,所以我会用伪代码来回答。由于您似乎在询问数组和子序列(即使您使用英文单词“sets”和“subsets”),我会这样做。我将使用该符号arr[m:n]来表示构造一个全新的长度数组,n - m + 1该数组m, m+1, ..., narr.

fun subsequences(arr, len) {
    answer = new empty array

    // base case 1: we haven't got a enough members in the
    // array to make a subsequence that long, so there are
    // no subsequences of that length
    if(arr.length < len) return answer

    // base case 2: we're only looking for trivial subsequences
    if(len <= 0) {
        trivial = new empty array
        prepend trivial to answer
        return answer
    }

    // choose the first element in the subsequence nondeterministically
    for each i from 0 to arr.length - 1 {
        // since we know the sequence starts with arr[i], the
        // remainder of the sequence must come from the elements
        // after index i
        subanswer = subsequences(arr[i+1:arr.length], len-1)
        for each subsequence in subanswer, prepend arr[i] to subsequence
        answer = concat(subanswer, answer)
    }
}
于 2011-09-06T23:53:48.847 回答