Php 查找仍可识别的单词,其中某些(最多)字符被另一个字符替换
我组装了这个小算法,它能够创建所有可能的字母和下划线排列的列表(tea->te_uu->t_ua->t_uea->t_uu->……) 指一组单词。然后比较排列并找到唯一的排列(tee&tea=>[tea,tee,t_a,t_e,_ea,_ee,__a,__e])。我的问题是,对于较大的单词,程序使用了太多的内存(毕竟,我正在创建一个包含所有可能组合的树)。我在考虑同时创建每个单词的树,然后在重复的过程中消除重复,但我不确定如何做到这一点 下面是我的代码中内存分配非常差的部分,用单词“tea”和“tee”作为测试用例: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”和“
$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个字符的单词。我会马上用一个更可靠的解决方案更新我的答案。还改变了变量在数组中的存储方式。并进行了一些性能检查。。