【问题标题】:compare scrambled words with an unscrambled wordlist php将加扰的单词与未加扰的单词列表 php 进行比较
【发布时间】:2009-12-20 18:12:54
【问题描述】:

我搜索了一种方法来将打乱的单词与一个充满未打乱单词的单词列表进行比较,例如:

打乱的单词是“lonbayb”,单词表中的某个地方是单词“babylon”。脚本应该向我显示未加密的单词

知道如何解决这个问题吗?

【问题讨论】:

    标签: php


    【解决方案1】:

    想到的一个简单解决方案是在比较之前按字母顺序对加扰和未加扰单词中的字母进行排序。我称之为“洗牌”:

    "babylon" ==> "abblnoy"
    

    实际上,您应该从参考词表中创建第二个词表,参考词表的条目会像这样随机排列。

    然后当您查看一个新单词并想知道它是否在列表中时,以同样的方式随机播放,您可以在随机播放的参考列表中进行简单的搜索。如果您按字母顺序对打乱的参考列表中的单词进行排序,您甚至可以对其进行二分搜索。或者你将洗牌的参考词放入哈希集或 b-tree 中......任何容易快速搜索的东西。

    【讨论】:

    • 是的,您可以使用每个单词的排序和未排序版本构建一个数据库表。当您想检查一个单词时,只需对它的字符进行排序并将其放入 SQL 中的 WHERE 子句中。如果有的话,你甚至会自动获得多个结果。
    • 当然,但仅适用于超过几兆字节的大型单词列表。少的话,我会使用内存中的数据结构,它的性能要好得多,而且与数据库相关的工作量更少。
    【解决方案2】:

    要随机播放单词,请使用str_shuffle()。 要将打乱的字符串与单词表进行比较,可以使用count_chars()

    class WordFinder
    {
        protected $_wordList;
        protected $_map;
    
        public function __construct(array $wordList)
        {
            $this->_wordList = $wordList;
        }
    
        protected function _initMap()
        {
            if(!is_array($this->_map)) {
                $this->_map = array();
                foreach($this->_wordList as $word) {
                    $key = count_chars($word, 3);
                    if(!isset($this->_map[$key])) {
                        $this->_map[$key] = array();
                    }
                    $this->_map[$key][] = $word;
                }
            }
        }
    
        public function findWords($searchWord)
        {
            $searchWord = count_chars($searchWord, 3);
            $this->_initMap();
            if(isset($this->_map[$searchWord])) {
                return $this->_map[$searchWord];
            }
            return false;
        }    
    }
    

    那就做吧

    $list   = array('evil', 'live', 'vile', 'cat');
    $finder = new WordFinder($list);
    var_dump($finder->findWords('evli'));
    

    这将返回

    array(3) {
      [0]=>
      string(4) "evil"
      [1]=>
      string(4) "live"
      [2]=>
      string(4) "vile"
    }
    

    编辑 我已将原始代码与此版本进行了交换,因为它在处理大型单词列表时的性能要好得多。我已经在我的 2,2 Ghz 双核上测试了上述内容,它会在 0.08 秒内完成对 findWords() 的 10000 个单词集合中的 10000 次调用。另一个版本需要 207 秒。请参阅旧版本的修订。

    【讨论】:

    • 天哪。在我的回答中,我有点凭空挑选了“shuffle”这个词,以避免与“sorting”混淆,这可能掩盖了我的意思。我不知道str_shuffle 是一个既定的PHP 函数,它做一些完全不同的事情,即改变字符的顺序随机。现在我正在考虑如何解决我可能无意中造成的任何混乱。
    • 没关系。他仍然可以使用str_shuffle 来打乱单词,因为count_chars 无论如何都会按字母顺序返回它们。不需要 1:1 的地图。
    猜你喜欢
    • 2020-11-07
    • 1970-01-01
    • 2012-11-07
    • 1970-01-01
    • 2019-04-27
    • 2014-09-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    相关资源
    最近更新 更多