从m个中选n个php编程,从m个数中选择n个数的实现

从m个数中选出n个数来 ( 0 < n <= m) ,要求n个数之间不能有重复,其和等于一个定值k。求一段程序,罗列所有的可能。 例如备选的数字是:11, 18, 12, 1, -2, 20, 8, 10, 7, 6 。 和k等于:18 那么组合的可能有:

[18]

[8,10]

[-2,20]

[12,6]

[11,7]

[11,1,6]

[1,10,7]

[12,-2,8]

[12,1,-2,7]

[11,1,-2,8]

解法一、

$nums = array(11,18,12,1,-2,20,8,10,7,6);

for($i=0;$i<1024;$i++){

$str = str_split(strrev(decbin($i)));

$ans = 0;

foreach($str as $k=>$v){

$ans +=$v *$nums[$k];

}

if($ans==18) {

echo '[';

foreach($str as $k=>$v){

if($v==1) {

echo $nums[$k];echo ",";

}

}

echo "]";

}

}

解法二、

/**

* 组合枚举

*/

function c($arr, $n, &$res, $pre = array())

{

if ($n == 0)

{

$res[] = $pre;

}

else

{

$count = count($arr);

for ($i = 0; $i < $count - $n + 1; $i++)

{

$temp = array_shift($arr);

c($arr, $n - 1, $res, array_merge($pre, array(

$temp

)));

}

}

}

// 处理数组

$arr = array(11, 18, 12, 1, -2, 20, 8, 10, 7, 6, 12, 6, 6, 6, -6 );

$sum = 18; // 条件和值

$count = count($arr);

// 从C(18,1) 循环到 C(18,18)

for ($i = 1; $i <= $count; $i++)

{

$res = array();

c($arr, $i, $res);

foreach ($res as $val)

{

if (array_sum($val) == $sum)

{

echo implode(' + ', $val), ' = ', $sum, PHP_EOL;

}

}

}

解法三、

function getCombine($arr, $n) {

$len = count($arr);

$total = pow(2, $len);

$ret = array();

for ($i = 1; $i < $total; $i++) {

$str = substr(str_repeat("0", $len) . decbin($i), -$len);

$tmparr = array_diff_key($arr, array_diff(str_split($str), array(

'1'

)));

if (array_sum($tmparr) == $n) {

$ret[] = implode($tmparr, ',');

}

}

return array_unique($ret);

}

$data = array(11, 18, 12, 1, -2, 20, 8, 10, 7, 6 );

$n = 18;

print_r(getCombine($data, $n));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值