我一直在寻找PHP阵列排列/组合问题全天..和仍然无法弄清楚:/
如果我有一个数组,如:
20 //key being 0
20 //key being 1
22 //key being 2
24 //key being 3
我需要一个像组合:
20, 20, 22 //keys being 0 1 2
20, 20, 24 //keys being 0 1 3
20, 22, 24 //keys being 0 2 3
20, 22, 24 //keys being 1 2 3
我现在有代码给我:
20, 22, 24
因为它不希望重复20 ......但是这就是我所需要的!
这里是我的代码。 它是直接从PHP的递归以获得字符串的所有可能性
function getCombinations($base,$n){
$baselen = count($base);
if($baselen == 0){
return;
}
if($n == 1){
$return = array();
foreach($base as $b){
$return[] = array($b);
}
return $return;
}else{
//get one level lower combinations
$oneLevelLower = getCombinations($base,$n-1);
//for every one level lower combinations add one element to them that the last element of a combination is preceeded by the element which follows it in base array if there is none, does not add
$newCombs = array();
foreach($oneLevelLower as $oll){
$lastEl = $oll[$n-2];
$found = false;
foreach($base as $key => $b){
if($b == $lastEl){
$found = true;
continue;
//last element found
}
if($found == true){
//add to combinations with last element
if($key < $baselen){
$tmp = $oll;
$newCombination = array_slice($tmp,0);
$newCombination[]=$b;
$newCombs[] = array_slice($newCombination,0);
}
}
}
}
}
return $newCombs;
}
我一直在玩与周围的($b == $lastEl)
线,没有运气
===============
问题我已经看了看,是不一样的或创建的内存不足的错误!:
- 我怎样才能在PHP中所有的排列顺序不重复?
- 置换-所有可能的两组数字
- 组合,配置与在PHP排列组合
- PHP阵列组合
- 找一个PHP数组的所有排列?
- PHP:如何得到一维数组的所有可能的组合?
- 从这个数组只选择唯一的数组值
- 找一个PHP数组的所有排列?
- PHP:如何得到一维数组的所有可能的组合?
- 从这个数组只选择唯一的数组值
- 我怎样才能在PHP中所有的排列顺序不重复?
- 算法来从n个返回k个元素的所有组合
- 查找数组,其总和等于组合(一个或多个)元件(一个或多个)的总和到一个给定数目的
- 组合,配置与在PHP排列组合
- PHP阵列组合
- PHP递归以获得字符串的所有可能性
- 如何返回数组的排列在PHP?
- 置换-所有可能的两组数字
- 在PHP子集和问题与MySQL
- 从阵列滤除任何重复的双值找到的独特组合
- 查找字符串的所有唯一排列,而不会产生重复
- 生成所有独特的排列
- 子总和恰好有k个整数?
我已经尝试了一些这些算法有12个项目的阵列,并最终运行内存。 不过我目前使用的是不给我一个内存不足错误的算法....但..我需要这些重复的!
Answer 1:
如果你不介意使用一对全局变量,你可以在PHP(从翻译做这个版本在JavaScript):
<?PHP
$result = array();
$combination = array();
function combinations(array $myArray, $choose) {
global $result, $combination;
$n = count($myArray);
function inner ($start, $choose_, $arr, $n) {
global $result, $combination;
if ($choose_ == 0) array_push($result,$combination);
else for ($i = $start; $i <= $n - $choose_; ++$i) {
array_push($combination, $arr[$i]);
inner($i + 1, $choose_ - 1, $arr, $n);
array_pop($combination);
}
}
inner(0, $choose, $myArray, $n);
return $result;
}
print_r(combinations(array(20,20,22,24), 3));
?>
OUTPUT:
Array ( [0] => Array ( [0] => 20
[1] => 20
[2] => 22 )
[1] => Array ( [0] => 20
[1] => 20
[2] => 24 )
[2] => Array ( [0] => 20
[1] => 22
[2] => 24 )
[3] => Array ( [0] => 20
[1] => 22
[2] => 24 ) )
Answer 2:
PEAR包Math_Combinatorics使这类问题很容易。 这需要相对较少的代码,它的简单和直接,这是很容易阅读。
$ cat code/php/test.php
<?php
$input = array(20, 20, 22, 24);
require_once 'Math/Combinatorics.php';
$c = new Math_Combinatorics;
$combinations = $c->combinations($input, 3);
for ($i = 0; $i < count($combinations); $i++) {
$vals = array_values($combinations[$i]);
$s = implode($vals, ", ");
print $s . "\n";
}
?>
$ php code/php/test.php
20, 20, 22
20, 20, 24
20, 22, 24
20, 22, 24
如果我有这个打包的功能,我会做这样的事情。
function combinations($arr, $num_at_a_time)
{
include_once 'Math/Combinatorics.php';
if (count($arr) < $num_at_a_time) {
$arr_count = count($arr);
trigger_error(
"Cannot take $arr_count elements $num_at_a_time "
."at a time.", E_USER_ERROR
);
}
$c = new Math_Combinatorics;
$combinations = $c->combinations($arr, $num_at_a_time);
$return = array();
for ($i = 0; $i < count($combinations); $i++) {
$values = array_values($combinations[$i]);
$return[$i] = $values;
}
return $return;
}
将返回一个数组的数组。 为了获取文本。 。 。
<?php
include_once('combinations.php');
$input = array(20, 20, 22, 24);
$output = combinations($input, 3);
foreach ($output as $row) {
print implode($row, ", ").PHP_EOL;
}
?>
20, 20, 22
20, 20, 24
20, 22, 24
20, 22, 24
Answer 3:
这个想法很简单。 假设你知道如何置换,然后如果你在一组它成为一个组合保存这些排列。 设置由定义采用重复值的照顾。 设置或一个HashSet PHP的euqivalent是SplObjectStorage和ArrayList是数组。 它不应该是很难改写。 我有在Java中实现:
public static HashSet<ArrayList<Integer>> permuteWithoutDuplicate(ArrayList<Integer> input){
if(input.size()==1){
HashSet<ArrayList<Integer>> b=new HashSet<ArrayList<Integer>>();
b.add(input);
return b;
}
HashSet<ArrayList<Integer>>ret= new HashSet<ArrayList<Integer>>();
int len=input.size();
for(int i=0;i<len;i++){
Integer a = input.remove(i);
HashSet<ArrayList<Integer>>temp=permuteWithoutDuplicate(new ArrayList<Integer>(input));
for(ArrayList<Integer> t:temp)
t.add(a);
ret.addAll(temp);
input.add(i, a);
}
return ret;
}
Answer 4:
为什么不直接使用二进制? 至少这样的简单,很容易理解的每行代码都这样做? 这里有一个功能我在一个项目我认为这是相当整洁,写了自己!
function search_get_combos($array){
$bits = count($array); //bits of binary number equal to number of words in query;
//Convert decimal number to binary with set number of bits, and split into array
$dec = 1;
$binary = str_split(str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT));
while($dec < pow(2, $bits)) {
//Each 'word' is linked to a bit of the binary number.
//Whenever the bit is '1' its added to the current term.
$curterm = "";
$i = 0;
while($i < ($bits)){
if($binary[$i] == 1) {
$curterm[] = $array[$i]." ";
}
$i++;
}
$terms[] = $curterm;
//Count up by 1
$dec++;
$binary = str_split(str_pad(decbin($dec), $bits, '0', STR_PAD_LEFT));
}
return $terms;
}
对于你的榜样,这个输出:
Array
(
[0] => Array
(
[0] => 24
)
[1] => Array
(
[0] => 22
)
[2] => Array
(
[0] => 22
[1] => 24
)
[3] => Array
(
[0] => 20
)
[4] => Array
(
[0] => 20
[1] => 24
)
[5] => Array
(
[0] => 20
[1] => 22
)
[6] => Array
(
[0] => 20
[1] => 22
[2] => 24
)
[7] => Array
(
[0] => 20
)
[8] => Array
(
[0] => 20
[1] => 24
)
[9] => Array
(
[0] => 20
[1] => 22
)
[10] => Array
(
[0] => 20
[1] => 22
[2] => 24
)
[11] => Array
(
[0] => 20
[1] => 20
)
[12] => Array
(
[0] => 20
[1] => 20
[2] => 24
)
[13] => Array
(
[0] => 20
[1] => 20
[2] => 22
)
[14] => Array
(
[0] => 20
[1] => 20
[2] => 22
[3] => 24
)
)
Answer 5:
有同样的问题,发现不同和位,更快的解决方案:
function bitprint($u) {
$s = array();
for ($n=0; $u; $n++, $u >>= 1){
if ($u&1){
$s [] = $n;
}
}
return $s;
}
function bitcount($u) {
for ($n=0; $u; $n++, $u = $u&($u-1));
return $n;
}
function comb($c,$n) {
$s = array();
for ($u=0; $u<1<<$n; $u++){
if (bitcount($u) == $c){
$s [] = bitprint($u);
}
}
return $s;
}
这一个从0生成整数的所有大小为m的组合到n-1,因此,例如M = 2,N = 3和调用梳(2,3)将产生:
0 1
0 2
1 2
它给你的索引位置,所以很容易通过索引指向数组元素。
编辑:具有输入梳(30,5)失败。 不知道为什么,任何人任何想法?
Answer 6:
清理使用strrev和/ foreach循环阿迪布拉德菲尔德的sugestion,只有获得独特的效果。
function search_get_combos($array = array()) {
sort($array);
$terms = array();
for ($dec = 1; $dec < pow(2, count($array)); $dec++) {
$curterm = array();
foreach (str_split(strrev(decbin($dec))) as $i => $bit) {
if ($bit) {
$curterm[] = $array[$i];
}
}
if (!in_array($curterm, $terms)) {
$terms[] = $curterm;
}
}
return $terms;
}
文章来源: PHP Find All (somewhat) Unique Combinations of an Array