使用什么算法?

时间:2012-06-22 00:50:42

标签: php vb.net algorithm

我正在为游戏文本扭曲做研究项目,文本将自动从字典中搜索单词然后加扰,并且还使用与此网站http://grecni.com/texttwist.php相同的概念自动处理要发现的单词。还需要提供一个我将用于我的项目的算法,并且我计划在这个网站http://grecni.com/texttwist.php中包含这个单词unscrambler但我不知道在我发布的网站上做什么算法可能用来做。任何人都知道什么类型,或者你所使用的算法,或者可以使用会得到相同的结果,非常感谢算法的一个例子。

3 个答案:

答案 0 :(得分:2)

您想要的数据结构称为Directed Acyclic Word Graph (dawg)

有关于此的问题已经回答:

Algorithm to get a list of all words that are anagrams of all substrings (scrabble)?

Writing an algorithm for scrabble

您也可以实现levenshtein algorithm,它可以实现几乎相同的结果: MySQL - Which Hash Algo should I use for this?

更新

在给自己一个挑战创建一个示例来演示算法之后我想出了这个,因为它来自为我的cms构建的插件,它包含在一个类中,但是你得到的想法有一个演示@ {{3} }

首先,我创建了一个id,word,sorted(word =实际单词,排序=按字母顺序排序的单词,例如:aardvark sorted is aaadkrrv)我只是在互联网上找到了一个英文单词列表。

表单发布字符串,然后字符串按字母顺序排序以匹配排序列的1:1,然后将字符串拆分为每个字符,然后按顺序查询直到最后一个字符。感兴趣的功能是str_sort,permute,swap也许它有一些兴趣......

<?php 
/**
 * Scrabble solver Plugin this file is "inline" included within the frontController class
 */
Class plugin{

    function __construct($core) {
        $this->core = $core;
        $this->plugin_path = SITE_ROOT.'/core/plugins/'.$this->core->router->action.'/';
        $this->request = explode('/',$this->core->router->request);
        //Assign Page meta tags ect
        $this->core->template->meta_keywords    = 'Text,Twist,Text Twist,word,letter,scrabble,unscrambler,unscramble,word finder,puzzle,anagram,scrabble,cheat,cheater,help,helper,solve,solver,free,php';
        $this->core->template->meta_description = 'Scrabble and Anagram like word solver tool to help unscramble letters and words and cheat at your favorite word puzzle';
        $this->core->template->page_title       = $this->core->template->site_name." - Scrabble and Anagram like word solver";
        $route = (isset($this->request[2])?$this->request[2]:null);
    }

    function load(){
        set_time_limit(0);
        $data=array('var'=>$this,'result'=>'','word'=>'','word_sort'=>'');

        switch($this->core->router->subaction){
            case "index":
                $string='';
                if($_SERVER['REQUEST_METHOD']=='POST'){
                    $string = substr(preg_replace('/[^a-zA-Z]/s', '', trim(strtolower($_POST['letters']))),0,8);
                    $data['word'] = $string;
                    $string = $this->str_sort($string);
                    $data['word_sort'] = $string;
                }
                $stringLen = strlen($string);

                $result = array();
                for($i=2;$i<=$stringLen;$i++){
                    $seq = substr($data['word_sort'],0,$i);

                    $rounds = explode('|',$this->permute($seq,0,strlen($seq)));
                    $r=$i;
                    foreach($rounds as $round){
                        $result[$r] = $this->get_words($round,strlen($seq));
                        $r++;
                    }
                }

                $data['result'] = $result;

                $this->core->template->content_center = $this->core->template->loadContentView(get_class(),$this->core->router->subaction,$data);
                $this->core->template->content_left   = '';
                $this->core->template->content_right  = '';
                break;

            case "update":
                $this->insert_word_lists();
                header('Location: '.SITE_URL.'/'.$this->core->router->action);
                die;
                break;

            case "api":
                header('Content-Type: application/json');
                echo 'No api for this plugin, perhaps one comming soon. ;p';
                break;

            default:
                header('Location: '.SITE_URL.'/'.$this->core->router->action);
                die;
                break;
        }
    }

    //Query Method to search for sequenced alphabetically sorted words.
    private function get_words($word,$stringLen){
        $chars = str_split($word,1);
        $sql = "SELECT DISTINCT `word` FROM `plugin_scrabble_words` WHERE ";
        foreach($chars as $char){
            $sql .=' `sorted` LIKE "%'.$char.'%" AND';
        }
        $sql = trim($sql,'AND');
        $sql .= ' AND LENGTH(sorted) = '.$stringLen;

        $statement = $this->core->db->prepare($sql);
        $statement->execute();

        $result = $statement->fetchAll(PDO::FETCH_ASSOC);

        return $result;
    }

    //A Model method for updating the database word list.
    private function insert_word_lists(){
        set_time_limit(0);
        $lists = glob($this->plugin_path."wordlists/*.txt");
        foreach ($lists as $list){
            $words = file($list);
            foreach($words as $word){
                $word = strtolower(preg_replace('/[^a-zA-Z]/s', '', $word));
                if($this->sql_check_word($word)===false){
                    $this->sql_put_word($word);
                }
            }
        }
    }

    //A Model method for checking the database specific word.
    private function sql_check_word($word){
        $sql = "SELECT `word` FROM `plugin_scrabble_words` WHERE `word` = :word";
        $statement = $this->core->db->prepare($sql);
        $statement->bindParam(':word', $word, PDO::PARAM_STR);
        $statement->execute();
        $result = $statement->fetchAll(PDO::FETCH_ASSOC);

        if(!empty($result)){
            return true;
        }else{
            return false;
        }
    }

    //A Model method for adding the word to the database.
    private function sql_put_word($word){
        $sql = "INSERT into `plugin_scrabble_words` (word,sorted) VALUES (:word,:sorted)";
        $statement = $this->core->db->prepare($sql);
        $sorted = $this->str_sort($word);
        $statement->bindParam(':word', $word, PDO::PARAM_STR);
        $statement->bindParam(':sorted', $sorted, PDO::PARAM_STR);
        $statement->execute();
    }


    //Sort Method that will sort a sring in alphabetical order
    private function str_sort($string) {
        $tmp = str_split($string);
        sort($tmp);
        return implode('',$tmp);
    }

    //Method to generate and return all permutations of the string with | delimiter.
    private function permute($str,$i,$n) {
        if ($i == $n){
            return $str.'|';
        } else {
            for ($j = $i; $j < $n; $j++) {
                $this->swap($str,$i,$j);
                $this->permute($str, $i+1, $n);
                $this->swap($str,$i,$j);
            }
        }
    }

    //Method to swap the char at pos $i and $j of $str.
    private function swap(&$str,$i,$j) {
        $temp = $str[$i];
        $str[$i] = $str[$j];
        $str[$j] = $temp;
    }
}
?> 

答案 1 :(得分:1)

一种方法是生成所有可能的字母排列,并将它们与字典相匹配。对于N字母字符序列,如果将字典保存在集合数据结构中,则需要O(N!)时间。

对于较短的序列(10个字符左右),这是一个非常好的策略。

对于较长的序列,您应该反过来。您可以遍历字典并确定您的字符序列是否包含要生成单词的字符。对于M字典元素,这将花费更多或更少的O(M)时间。有多种方法可以加快这种技术,例如预先计算每个字典条目中每个字母的数量。

答案 2 :(得分:1)

编辑:我下面的绅士对这个主题进行了更加严格和彻底的处理,所以我会指导你的解释(使用大的O符号,我的......很尴尬)。

实际上,虽然VanDang称之为“天真的方法”,但测试给定的有限字符集的所有可能组合并没有错。只要一个人被阻止提供任意数量的字符,最多有n个字母组合(n =字母数,假设没有重复),并且,因为英语单词不得到这么久,测试每个组合都不会那么糟糕。

毕竟,耗尽方法实际上是在生成硬件描述时优化大布尔表达式的可接受方法。