php – 生成所有可能的组合
我有一个应用程序,用户可以通过从菜单中选择选项来自定义他们要购买的产品.此菜单包含许多部分,每个部分可能包含多重选项的复选框列表,或者只能选择一个选项时的单选按钮.用户必须在每个部分中至少选择一个选项.菜单结构是这样的:
$sections = array(); $sections[1] = array( 'multichoice' => true,'options' => array('A','B','C') ); $sections[2] = array( 'multichoice' => false,'C','D') ); $sections[3] = array( 'multichoice' => false,'B') ); $sections[4] = array( 'multichoice' => true,'D','E') ); 示例:三明治是产品.面包类型是一个选择的“部分”.您可能需要清淡面包,黑面包,牛奶面包或素食面包.本节下只能选择一个选项.现在在“沙拉”部分,您可以选择多种类型的沙拉添加到面包中. 现在,我的老板要求我创建一个列出所有可能组合的页面,以防用户懒得自己构建产品.所以我必须能够生成这样的结构: $combinations = array( array( 1 => array('A','B'),2 => 'A',3 => 'A',4 => array('B','E') ),array( 1 => array('A'),2 => 'B',4 => array('A','B') ) // etc... ); 我已经设法使用随机方法找到所有可能的组合,生成哈希值以与已生成的内容进行比较.这实际上有效,但运行速度非常慢(基本上这是蛮力): ... function generate(){ $result = array(); $ids = array(); foreach($this->getSections() as $sect){ $items = $this->getSectionOptions($sect['id']); if($sect['multi']=='N'){ $item = $items[rand(0,count($items)-1)]; $result[$sect['id']] = $item['id']; $ids[] = $item['id']; } else { $how_many = rand(1,count($items)); shuffle($items); for($i=1;$i<=$how_many;$i++){ $item = array_shift($items); $result[$sect['id']][] = $item['id']; $ids[] = $item['id']; } } } sort($ids); return array( 'hash' => implode(',',$ids),'items' => $result ); } function generateMany($attempts=1000){ $result = array(); $hashes = array(); for($i=1;$i<=$attempts;$i++){ $combine = $this->generate(); if(!in_array($combine['hash'],$hashes)){ $result[] = $combine['items']; $hashes[] = $combine['hash']; } } return $result; } ... 我希望你的帮助能够创造更精确,更快捷的东西.请记住,每个组合必须至少有一个选项.并且还要记住,多选区段中的选项顺序是无关紧要的(即E,B,A与B,E,A相同) 谢谢 解决方法
谢谢这是一个非常有趣的拼图!
那我怎么解决,递归递归递归:D 我从多选开始,因为它是最难选择的! (实际上它也会解决混合问题) 说明 为了解释我是如何使用它的,让我们举一个选择A,C的例子.我们将有以下组合: A B A B C A C B B C C 如果我们仔细观察,我们可以看到一些模式.让我们把结果列表作为第一个元素(A) B B C C --- B B C C 嗯,有趣……现在让我们再拿第一个元素(B) C --- C 这是一个简单的案例,但这将在任何大小的情况下发生. 所以我已经使递归脚本到达最后,然后向后添加迭代组合并将其与前一个值复制. 瞧!就是这个! 对于需要所有元素的最终混合,我做了一个非常相似的方法,但每个必须包含1个元素 而且速度非常快!
如果你发现任何错误我:D 码 https://gist.github.com/MLoureiro/a0ecd1ef477e08b6b83a (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |