一鲁驶、組合算法
給定一非重復(fù)字符串所有的組合脸秽,形如 abc,則
Q1:輸出所有組合 a糙麦,b祭刚,c牌捷,ab,ac涡驮,bc暗甥,abc;
Q2:輸出指定長度的組合捉捅,如2個長度則輸出 ab撤防,ac,bc棒口;
Q3:計算組合總數(shù)寄月。
1、組合算法一——獲取所有組合
/**
* get_combinations 獲取指定字符串的所有組合
* @param string $str 目標(biāo)字符串
* @param array $comb 組合容器
* @return bool | array
* @author Mike Lee
*/
function get_combinations($str = '', &$comb = array())
{
if (trim($str) == '' || ! $str) return false;
if (strlen($str) <= 1) {
$comb[] = $str;
} else {
$str_first = $str[0];
$comb_temp = get_combinations(substr($str, 1), $comb);
$comb[] = $str_first;
foreach ($comb_temp as $k => $v) {
$comb[] = $str_first . $v;
}
}
return $comb;
}
2陌凳、組合算法二——獲取指定長度的組合
待更新
3、組合算法三——計算組合數(shù)
/**
* count_combinations 計算組合數(shù)
* @param int $n
* @param int $m
* @return int $count
* @author Mike Lee
*/
function count_combinations($n= 1, $m = false)
{
$n = (int) $n;
if ($n < 0) return false;
if ($m === false) {
$count = pow(2, $n) - 1;
} else {
$m = (int) $m;
if ($m < 0) return false;
if ($m > $n) return false;
if ($m == $n || $m == 0) {
$count = 1;
} else {
$count = factorial($n) / (factorial($m) * factorial($n - $m));
}
}
return $count;
}
/**
* factorial 階乘
* @param int $num
* @return int $result
*/
function factorial($num = 0)
{
$num = (int) $num;
if ($num < 0) return false; // 負(fù)數(shù)沒有階乘
if ($num > 1) {
$result = $num * factorial($num - 1);
} else {
$result = 1; // 0和1的階乘均為1
}
return $result;
}
4内舟、組合算法四——數(shù)組組合
給定若干一維索引數(shù)組合敦,對各數(shù)組中的值進(jìn)行組合;
例如 $a = [1, 2]验游,$b = ['a', 'b']充岛,那么將有如下組合:
[1, 'a'],[1, 'b']耕蝉,[2, 'a']崔梗,[2, 'b'];
下面算法實現(xiàn) foo 和 foo2 函數(shù)只是傳參不同垒在,效果一致蒜魄。
function foo(array $arr)
{
$num = count($arr);
if ($num === 0) return false;
if ($num === 1) return $arr[0];
while(count($arr) > 1) {
$arr_first = array_shift($arr);
$arr_second = array_shift($arr);
$c = array();
foreach ($arr_first as $v) {
$v = (array) $v;
foreach ($arr_second as $val) {
$c[] = array_merge($v, (array) $val);
}
}
array_unshift($arr, $c);
unset($c);
}
return $arr[0];
}
function foo2()
{
$num = func_num_args();
if ($num === 0) return false;
$all = func_get_args();
if ($num === 1) return $all[0];
while(count($all) > 1) {
$all_first = array_shift($all);
$all_second = array_shift($all);
$c = array();
foreach ($all_first as $v) {
$v = (array) $v;
foreach ($all_second as $val) {
$c[] = array_merge($v, (array) $val);
}
}
array_unshift($all, $c);
unset($c);
}
return $all[0];
}
二、排列算法
給定字符串一非重復(fù)字符串场躯,例如 abc谈为,則
Q1:輸出所有排列 a,b踢关,c伞鲫,ab,ac签舞,ba秕脓,bc柒瓣,ca,cb吠架,abc芙贫,acb,bac诵肛,bca屹培,cab,cba怔檩;
Q2:輸出指定長度的排列褪秀,如2個長度則輸出 ab,ac薛训,ba媒吗,bc,ca乙埃,cb闸英;
Q3:計算排列總數(shù)。
1介袜、排列算法一——獲取所有排列
待更新