我试图生成一组字符串的所有可能的组合,使用每个字符串的最大一次。
- 输出字符串的长度没有定义(最大长度是给定字符串的数量,因为你只能用一次)
- 例如,stringset
array('A','B')
将产生的A,B,AB,BA。 - 例如,stringset
array('ABC', 'Z')
将产生'ABC', 'Z', 'ZABC'和'ABCZ'。 - 甲stringset可以具有相同的条目,并且输出简化版,需要TE是unique.For例如,stringset
array('A', 'A')
将产生'A', 'A', 'AA', 'AA' ; (其实我并不需要重复,但我不想让事情变得更加困难)
我知道2串有4个组合(2 => 4)和3 => 15,4 => 64,5 => 325 ...
因为我不是一个程序员,我发现它至少是“具有挑战性”。 嵌套循环很快地方太复杂。 一个更简单的解决方案可以被发现在与字符串数组的索引图案。 但是,这给了我重复使用的串...
$strings = array('T','O','RS');
$num = 0;
$stringcount = count($strings);
$variations = array(0,1,4,15,64,325,1956,13699,109600,986409);
for($i=0;$i<$variations[$stringcount];$i++){
$index = base_convert($num, 10, $stringcount);
$array_of_indexes = str_split($index);
$out='';
for($j=0;$j<count($array_of_indexes);$j++){
$out .= $strings[$array_of_indexes[$j]];
}
echo $out . '<br />';
$num++;
}
结果:TöRS OT OO ORS RST RSO RSRS OTT OTO OTRS OOT OOO OORS
不好,很多重复+许多有效组合不包括
我知道,这个解决方案是错误的方法很多,但我不知道从哪里开始? 有什么建议? Thx提前!
在数学术语中,你所要求的所有可能的非空下令输入集的子集 。 在整数序列的在线百科全书,出现这样的序列号作为序列A007526 -注意,这个序列是始于4,15,64,325完全一样,你已经发现。
这个问题承认在Python很短的,高效的解决方案,所以我打算先张贴的解决方案:
def gen_nos(s):
for i in sorted(s):
yield i
s.remove(i)
for j in gen_nos(s):
yield i+j
s.add(i)
例:
>>> list(gen_nos(set(['a', 'b', 'c'])))
['a', 'ab', 'abc', 'ac', 'acb', 'b', 'ba', 'bac', 'bc', 'bca', 'c', 'ca', 'cab', 'cb', 'cba']
需要注意的是sorted
不是绝对必要的; 它只是确保输出按字典顺序排序(否则,这些元件在组顺序,其实质上是任意迭代)。
将其转换为PHP,我们基本上使用递归函数与一个额外的数组参数保存结果:
function gen_nos(&$set, &$results) {
for($i=0; $i<count($set); $i++) {
$results[] = $set[$i];
$tempset = $set;
array_splice($tempset, $i, 1);
$tempresults = array();
gen_nos($tempset, $tempresults);
foreach($tempresults as $res) {
$results[] = $set[$i] . $res;
}
}
}
例:
$results = array();
$set = array("a", "b", "c");
gen_nos($set, $results);
var_dump($results);
产生
array(15) {
[0]=>
string(1) "a"
[1]=>
string(2) "ab"
[2]=>
string(3) "abc"
[3]=>
string(2) "ac"
[4]=>
string(3) "acb"
[5]=>
string(1) "b"
[6]=>
string(2) "ba"
[7]=>
string(3) "bac"
[8]=>
string(2) "bc"
[9]=>
string(3) "bca"
[10]=>
string(1) "c"
[11]=>
string(2) "ca"
[12]=>
string(3) "cab"
[13]=>
string(2) "cb"
[14]=>
string(3) "cba"
}
下面是我的实现,我已经很长一段时间使用组合和排列的基本数学definiton写的。 也许这可以帮助。
<?php
/**
* Generate all the combinations of $num elements in the given array
*
* @param array $array Given array
* @param int $num Number of elements ot chossen
* @param int $start Starter of the iteration
* @return array Result array
*/
function combine($array, $num, $start = 0) {
static $level = 1;
static $result = array();
$cnt = count($array);
$results = array();
for($i = $start;$i < $cnt;$i++) {
if($level < $num ) {
$result[] = $array[$i];
$start++;
$level++;
$results = array_merge($results, combine($array, $num, $start));
$level--;
array_pop($result);
}
else {
$result[] = $array[$i];
$results[] = $result;
array_pop($result);
}
}
return $results;
}
/**
* Generate all the permutations of the elements in the given array
*/
function permute($array) {
$results = array();
$cnt = count($array);
for($i=0;$i<$cnt;$i++) {
$first = array_shift($array);
if(count($array) > 2 ) {
$tmp = permute($array);
}
elseif(count($array) == 2) {
$array_ = $array;
krsort($array_);
$tmp = array($array, $array_);
}
elseif(count($array) == 1) {
$tmp = array($array);
}
elseif(count($array) == 0) {
$tmp = array(array());
}
foreach($tmp as $k => $t) {
array_unshift($t, $first);
$tmp[$k] = $t;
}
$results = array_merge($results, $tmp);
array_push($array, $first);
}
return $results;
}
$strings = array('T', 'O', 'RS');
$strings_count = count($strings);
$combinations = array();
for ($i = 1; $i <= $strings_count; $i++) {
$combination = combine($strings, $i, 0);
$combinations = array_merge($combinations, $combination);
}
$permutations = array();
foreach($combinations as $combination) {
$permutation = permute($combination);
$permutations = array_merge($permutations, $permutation);
}
print_r($combinations);
print_r($permutations);
这是我天真的递归实现:
<?php
// Lists all ways to choose X from an array
function choose($x, array $arr) {
$ret = array();
if ($x === 0) {
// I don't think this will come up.
return array();
} else if ($x === 1) {
foreach ($arr as $val) {
$ret[] = array($val);
}
} else {
$already_chosen = choose($x - 1, $arr);
for ($i = 0, $size_i = sizeof($arr); $i < $size_i; $i++) {
for ($j = 0, $size_j = sizeof($already_chosen); $j < $size_j; $j++) {
if (!in_array($arr[$i], $already_chosen[$j])) {
$ret[] = array_merge(
array($arr[$i]),
$already_chosen[$j]
);
}
}
}
}
return $ret;
}
function choose_all($arr) {
for ($i = 1, $size = sizeof($arr); $i <= $size; $i++) {
foreach (choose($i, $arr) as $val) {
echo implode(":", $val).PHP_EOL;
}
}
}
choose_all(array(
"A",
"B",
));
echo "--".PHP_EOL;
choose_all(array(
"ABC",
"Z",
));
echo "--".PHP_EOL;
choose_all(array(
'T',
'O',
'RS'
));
(不知道我做什么,当然)
http://codepad.org/5OKhsCJg
您需要在阵列上有什么本质上是一个笛卡尔乘积。 这是一套数学的一个方面,是数据库系统以及正式的建模语言常见。 将会有一些应用的解决方案,如果你谷歌这个词的PHP。
(我从来没有直接做过任何PHP这就是为什么我不希望你张贴了不正确的(或哈克)解决方案,但希望这将有助于引导你沿着正确的方向)!