Php 查找仍可识别的单词,其中某些(最多)字符被另一个字符替换

Php 查找仍可识别的单词,其中某些(最多)字符被另一个字符替换,php,memory,memory-management,Php,Memory,Memory Management,我组装了这个小算法,它能够创建所有可能的字母和下划线排列的列表(tea->te_uu->t_ua->t_uea->t_uu->……) 指一组单词。然后比较排列并找到唯一的排列(tee&tea=>[tea,tee,t_a,t_e,_ea,_ee,__a,__e])。我的问题是,对于较大的单词,程序使用了太多的内存(毕竟,我正在创建一个包含所有可能组合的树)。我在考虑同时创建每个单词的树,然后在重复的过程中消除重复,但我不确定如何做到这一点 下面是我的代码中内存分配非常差的部分,用单词“tea”和“

我组装了这个小算法,它能够创建所有可能的字母和下划线排列的列表(tea->te_uu->t_ua->t_uea->t_uu->……) 指一组单词。然后比较排列并找到唯一的排列(tee&tea=>[tea,tee,t_a,t_e,_ea,_ee,__a,__e])。我的问题是,对于较大的单词,程序使用了太多的内存(毕竟,我正在创建一个包含所有可能组合的树)。我在考虑同时创建每个单词的树,然后在重复的过程中消除重复,但我不确定如何做到这一点

下面是我的代码中内存分配非常差的部分,用单词“tea”和“tee”作为测试用例:

$word1 = "tea tee";
$word1 = preg_split('/ +/', $word1);
$word1 = array2d($word1);
$word1 = get_multipleCombinations($word1);
$word1 = compare_combinations($word1);

foreach($word1 as $key1=>$level1){
    foreach($level1 as $key2=>$level2){
        foreach($level2 as $key3=>$level3){
            echo $word1[$key1][$key2][$key3];       
    }

    echo " ";
}

}

function array2d($words){
    $count = count($words);

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

        $words[$i] = str_split($words[$i]);
    }
    for ($i = 0; $i <= $count-1; $i++) {

        for ($j = 0; $j <= count($words[$i])-1; $j++){

            $words[$i][$j] = array("_", $words[$i][$j]);
        }
    }
    return $words;
}

function get_combinations($arrays) {
    $result = array(array());
    foreach ($arrays as $key => $values) {
        $temp = array();
        foreach ($result as $results) {
            foreach ($values as $value) {
                $temp[] = array_merge($results, array($key => $value));
            }
        }
        $result = $temp;
    }
    return $result;
}

function get_multipleCombinations($array){
    $count0 = count($array)-1;

    for ($i = 0; $i <= $count0; $i++){
        $result[$i] = get_combinations($array[$i]);
    }
    return($result);

}

function compare_combinations($array){
    $count = count($array)-1;

    for($j = 0; $j <= $count; $j++){
        for($z = 0; $z <= $count; $z++){
            if($j !== $z){
                for($i = 0; $i <= count($array[$j])-1; $i++){
                    if(count($array[$j]) === count($array[$z]) && $array[$j][$i] === $array[$z][$i]){
                        $array[$j][$i] = array("");
                        $array[$z][$i] = array("");
                    }
                }
            }
        }
    }
    return($array);

}
$word1=“茶座”;
$word1=预拆分('/+/',$word1);
$word1=array2d($word1);
$word1=获取多个组合($word1);
$word1=比较组合($word1);
foreach($word1作为$key1=>$level1){
foreach($level1作为$key2=>$level2){
foreach($level2作为$key3=>$level3){
回显$word1[$key1][$key2][$key3];
}
回声“;
}
}
函数数组2d($words){
$count=count($words);

对于($i=0;$i我想提出的第一个主题是所谓的大O表示法。我不想费心详细解释它,所以这里有一个链接:

我马上看到的都是嵌套for循环,这严重影响了性能。如果可能的话,建议编写递归函数,而不是嵌套for语句(一般来说循环更少)

下面是一些代码,可以更好地指导您使用递归性,而不是嵌套for循环

function getWordCombos(String $word) {
    $chars = str_split($word);
    return insertHyphens($chars);
}

function insertHyphens(Array $chars, $vals=[], $index=0) {
    //make an untarnished copy of original chars
    $original = $chars;

    for($i=$index; $i<count($original); $i++) {
        $chars = $original;

        //this alters $chars itself, which is why we set $chars = $original above
        array_splice($chars, $i, 1, '_');
        $tempWord = implode('', $chars);

        //setting and checking keys in array faster than in_array
        if (!isset($vals[$tempWord])) {
            $vals[$tempWord]=1;
        }

        //recursive bit
        $vals = insertHyphens($chars, $vals, $index + 1);
    }
    return $vals;
}
$words = "tea tee tail team";

$words = preg_split('/ +/', $words);
$unique = array();
foreach($words as $word) {
    $unique = array_merge($unique, getWordCombos($word));
}

var_dump(implode(' ', array_keys($unique)));
函数getWordCombos(字符串$word){ $chars=str_split($word); 返回插入母鸡($chars); } 函数insertHyphens(数组$chars,$vals=[],$index=0){ //制作一份原始字符的无污损副本 $original=$chars;
对于($i=$index;$iOh-wow,我真的把它搞糟了。但是,这个解决方案不考虑下划线没有连接在一起的组合(比如t_i_)。问题是,每个单词都有2^n个组合,因此,从本质上讲,很多组合最终都会被存储。我想做的是生成同一循环中所有单词的树,并在循环中添加验证。因此,它会在生成所有组合之前删除多余的组合。此外,可能还有一种方法可以因为我们已经知道字母的位置相同,所以我认为可能根本不需要生成所有的字母,只要找到每个单词的唯一组合,它就应该停止(因为它是从大多数下划线到最小下划线生成的)啊,是的,我在测试中没有尝试使用4个字符的单词。我会马上用一个更可靠的解决方案更新我的答案。还改变了变量在数组中的存储方式。并进行了一些性能检查。。