PHP中的Anagram算法

时间:2012-05-17 14:50:42

标签: php algorithm anagram

我完全是PHP的新手。今天我遇到了一个我不知道如何解决的问题,即使在搜索谷歌和挖掘SOF之后。这是Anagram算法。

所以基本上,我理解这里的问题:当用户输入一个字符串时,我将其拆分并与我的库(给定数组)进行比较,然后我将不得不通过2-3 -...等字符加入它再次比较,它正是我现在被困住的地方,我不知道如何加入数组的元素。

这是我正在实现的代码,也是一个示例字典。

我有一个自制的字典,在数组$ dict中包含这些元素。我有一个表单供用户输入字符串,输入的字符串将传递给下面的代码并声明为$ anagram。我必须将输入的字符串拆分为与我的字典进行比较。但是我不知道怎么加入它们就像比较2个字母,3个字母......等等......到字典中。

<?php

$dict = array(
'abde',
'des',
'klajsd',
'ksj',
'hat',
'good',
'book',
'puzzle',
'local',
'php',
'e');

$anagram = $_POST['anagram'];
//change to lowercase
$anagram = strtolower($anagram);

//split the string
$test = str_split($anagram);

//compare with $dict for the first split without joining
for ($i=0; $i<strlen($anagram); $i++) {
    if ($test[$i]==$dict[$i]) {
        echo $test[$i]."<br />";
    }
}

//problem: how to join elements of the array in the loops
//like user inputs "hellodes"
//after echo "e", how to join the elements like: h-e,h-l,h-l,h-o,h-d,h-e,h-s
//and then h-e-l,h-e-l,h-e-o...etc...
?>

我希望算法尽可能简单,因为我完全是个新手。我很抱歉因为我的英语不太好。 最好的祝福, Khiem Nguyen。

6 个答案:

答案 0 :(得分:19)

(我将此作为一个单独的答案加入,因为这是处理问题的另一种方式,而不是我在第一期中提到的)

这是一种更复杂的方法,可以解决字典中哪些单词是您正在寻找的单词的一部分;我会让读者知道它是如何工作的。

它使用因子分解来判断一个单词是否是另一个单词的字谜。它将做的是为每个字母分配一个独特的主要价值;您可以通过将所有值相乘来计算给定单词中字母的值。例如,CAT为37 * 5 * 3或510.如果您的目标词因素相同,则可以确定该词是另一个的字谜。

我根据他们在英国英语中的常见程度订购了素数,以保持较小的因子。

<?php

function factorise($word)
{
    // Take a number, split it into individual letters, and multiply those values together
    // So long as both words use the same value, you can amend the ordering of the factors 
    // as you like

    $factors = array("e" => 2, "t" => 3, "a" => 5, "o" => 7, "i" => 11,
        "n" => 13, "s" => 17, "h" => 19, "r" => 23, "d" => 29,
        "l" => 31, "c" => 37, "u" => 41, "m" => 43, "w" => 47,
        "f" => 53, "g" => 59, "y" => 61, "p" => 67, "b" => 71,
        "v" => 73, "k" => 79, "j" => 83, "x" => 89, "q" => 97,
        "z" => 101);

    $total = 1;

    $letters = str_split($word);

    foreach ($letters as $thisLetter) {
        if (isset($factors[$thisLetter])) {
            // This will skip any non-alphanumeric characters.
            $total *= $factors[$thisLetter];
        }
    }

    return $total;
}

$searchWord = "hasted";

$dict = array("abde", "des", "klajsd", "ksj", "hat", "hats");

$searchWordFactor = factorise($searchWord);

foreach ($dict as $thisWord) {
    // Factorise each word that we're looking for
    // If the word we've just factored is an exact divisor of the target word, then all the 
    // letters in that word are also present in the target word
    // If you want to do an exact anagram, then check that the two totals are equal

    $dictWordFactor = factorise($thisWord);

    if (($searchWordFactor % $dictWordFactor) == 0) {
        print ($thisWord . " is an anagram of " . $searchWord . "<br/>");
    }
}

对于它的价值,我认为这是一个更优雅的解决方案 - 您可以通过预先计算字典中的值来加快速度。如果你仔细研究字典中每个单词的因子,你可以直接在数据库中进行搜索:

SELECT word FROM dictionary WHERE wordFactor='$factorOfThisWord'

答案 1 :(得分:2)

我无法完全遵循您的代码所做的事情;但是如果你想要一个简单的anagram检查器,那么伪代码将是:

get array of letters in my anagram
for each word in the dictionary
    get array of letters in this word
    for each letter in my anagram
        is this letter also in the word?
            if no, move on to the next word
    if we get here, it's an anagram

你可以做一些额外的事情 - 你可以确保anagram和字典单词的长度相同(如果它们不是,它们不能是字谜);你还需要弄清楚如何处理字典单词中多次出现的字母,但只需要在字谜单词中处理一次(例如,上面的代码会将'aa'报告为'a'的字谜)< / p>

答案 2 :(得分:0)

我无法理解您的问题,您对代码的解释以及代码本身。你想检查一个任意单词是否是字典中某个单词的字谜吗?

这很简单 - 制作一个包含26个整数的数组。以小写形式输入输入单词,将每个字母的数组[letter - 'a'](或等效的php)增加1。

然后浏览字典并以相同的方式生成每个单词生成array_dict,如果array [i] == array_dict [i],则检查i = 0 ... 25。如果它们都是相同的,那么这些词就是字谜。当然,在每个单词后面将array_dict设置为零。

另一种方法是对字符串中的字母进行排序,并简单地比较排序后的字符串。如果您允许修改/预处理字典,那么这个很好 - 您可以对字典进行预先排序,然后对输入字进行排序并将其与字典单词进行比较。最佳解决方案可能是创建一个(用C#术语,我不知道php抱歉)

Dictionary<string, List<string>>

并通过对每个单词进行排序来预处理您的字典,在字典中查找它,如果列表不存在则创建它,并且在任何一种情况下都将该单词添加到列表中。然后,当用户输入单词时,您可以对其进行排序并返回字典[sortedword]作为结果 - 所有字谜在基本恒定的时间内找到(输入字符串长度为nlogn,但字典大小为常量)。

答案 3 :(得分:0)

$dictionary = array("kayak");

$anagram = "kayak";

$anagramSorted = sortString($anagram);


foreach ($dictionary as $word)
{
    $wordSorted = sortString($word);
    if ($wordSorted == $anagramSorted)
    {
       echo 'true';
    }
}

function sortString($s)
{
    $chars = array();
    $length = strlen($s);
    for ($i=0;$i<$length;$i++)
    {
       $chars[] = $s[$i];
    }
    sort($chars);

    return implode("",$chars);
}

答案 4 :(得分:0)

尝试使用字符串shuffle函数?

str_shuffle ( string $str )

这是一些伪代码:

Get random string from array
store string copy (Not shuffled)
string shuffle another copy
echo shuffled string
get users guess
parse guess (Remove illegal characters)
if parsed guess = string
    reward
else
    ?let user try again?

答案 5 :(得分:0)

此函数将获取字符串并返回字符串中存在的计数字谜。

function countingAnagrams($str)
    {
        $str_arry = [];
        $anagrams = 0;
        $str_arry= explode(' ', $str);
        for ($i = 0; $i < count($str_arry); $i++) {
            $str_cmp = $str_arry[$i];
            for($k = 0; $k < count($str_arry); $k++){
                if($i != $k){
                    $str_rev = $str_arry[$k];
                    if (count_chars($str_cmp, 1) == count_chars($str_rev, 1))
                    {
                        unset($str_arry[$i]);
                        $str_arry = array_values($str_arry);
                        $anagrams++;
                    }
                }
            }
        }
        return $anagrams;
    }


echo  countingAnagrams('cars are residing on my arcs');