【问题标题】:Create every possible combination in PHP在 PHP 中创建所有可能的组合
【发布时间】:2015-07-18 01:42:58
【问题描述】:

所以,我正在尝试获取一组单词的所有可能组合的列表。

输入文本 "1, 2" 和值为 ("1" => "a", "b", "c") 和 ("2" => "d", "e"),我会得到类似的东西:

a, d
b, d
c, d
a, e
b, e
c, e

使用我现在拥有的代码,我只得到:

a, d
b, d
c, d

我该如何解决这个问题?

代码:

foreach ($words as $word)
{
    for ($i = 0; $i < count($array); $i++) //For every value
    {
        $key = array_keys($array[$i])[0];
        if ($word === $key)
        {
            $syn = explode("|", $array[$i][$key]); //Get all synonyms
            foreach ($syn as $s) //For each synonym within
            {

                $potential[] = implode(" ", str_replace($key, $s, $words));
            }
        }
    }
}

该过程针对输入文本中的每个单词,我们想要遍历整个值数组。在那里,我们有其他数组(“原始”=>“同义词”)。从那里,我们遍历每个同义词并将其添加到潜在组合列表中。

【问题讨论】:

    标签: php arrays combinations


    【解决方案1】:

    涉及几个步骤:

    1. 将同义词列表缩小到仅在字符串中找到的同义词
    2. 创建用于构建最终句子的模板
    3. 获取所有同义词combinations 并将它们应用于模板

    以下将做到这一点:

    $dict = [
        '1' => ['a', 'b', 'c'],
        '2' => ['d', 'e'],
    ];
    
    $str = '2, 1';
    
    class SentenceTemplate implements IteratorAggregate
    {
        private $template;
        private $thesaurus;
    
        public function __construct($str, $dict)
        {
            $this->thesaurus = [];
    
            $this->template = preg_replace_callback('/\w+/', function($matches) use ($dict) {
                $word = $matches[0];
                if (isset($dict[$word])) {
                    $this->thesaurus[] = $dict[$word];
                    return '%s';
                } else {
                    return $word;
                }
            }, $str);
        }
    
        public function getIterator()
        {
            return new ArrayIterator(array_map(function($args) {
                return vsprintf($this->template, $args);
            }, $this->combinations($this->thesaurus)));
        }
    
        private function combinations($arrays, $i = 0) {
            if (!isset($arrays[$i])) {
                return array();
            }
            if ($i == count($arrays) - 1) {
                return $arrays[$i];
            }
    
            // get combinations from subsequent arrays
            $tmp = $this->combinations($arrays, $i + 1);
    
            $result = array();
    
            // concat each array from tmp with each element from $arrays[$i]
            foreach ($arrays[$i] as $v) {
                foreach ($tmp as $t) {
                    $result[] = is_array($t) ? array_merge(array($v), $t) : array($v, $t);
                }
            }
    
            return $result;
        }
    }
    
    $sentences = new SentenceTemplate($str, $dict);
    foreach ($sentences as $sentence) {
        echo "$sentence\n";
    }
    

    Demo

    【讨论】:

    • 这似乎对我不起作用。数据:dict ( "hello" =&gt; array("hey", "whats up"...), "name" =&gt; array("nomenclature"...))str = "hello my name is" - 我得到的唯一结果是 0=Array my is
    • @AdamM 我会用你的输入再次测试它,看看我错过了什么:)
    • @AdamM 我用我的代码运行了你的输入,它工作正常;我做了一个小更新,因为我没有在底部使用$str
    【解决方案2】:

    假设 1 和 2 都是数组,您可以进行嵌套 for 循环以获得所有可能的组合。

    $one = array("a", "b", "c");
    $two = array("d", "e");
    
    
    $final_array = array();
    
    for($a = 0; $a<sizeof($one); $a++) 
    {
        for($b = 0; $b<sizeof($two); $b++) 
        {
    
                $final_array[] = $one["$a"] . $two["$b"];
        }
    }
    
    print_r($final_array);
    

    这将打印出来

    Array ( [0] => ad 
            [1] => ae 
            [2] => bd 
            [3] => be 
            [4] => cd 
            [5] => ce )
    

    希望这就是你要找的。​​p>

    【讨论】:

    • 这对我没有帮助,因为我不知道我将拥有多少个数组。我可能有一个,我可能有一百个。因此,为什么我需要某种可以处理任意数量的函数:)
    • foreach 循环可能会比for 循环重复调用sizeof 更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多