suchen

Heim  >  Fragen und Antworten  >  Hauptteil

python - php查找算法

一个文件有30w条数据!每行一个数据

同行词!比如post stop tops这样的是同行词
你用什么办法把里面的所有这样数据找出来

求个思想

phpcn_u1582phpcn_u15822752 Tage vor428

Antworte allen(3)Ich werde antworten

  • phpcn_u1582

    phpcn_u15822017-05-16 13:04:53

    使用linux命令来完成需求。例子

    统计文件夹下包含Action( 数量
    grep Action\( ~/www/pms/app/app/controllers/*.php | wc -l

    Antwort
    0
  • PHPz

    PHPz2017-05-16 13:04:53

    我的建议是写一个特别的排序算法,然后用usort来排序,这样同行词都排在一起了,然后依序输出

    排序算法大致的逻辑是

    int cmp($left, $right) {
       //如果长度都不一致,直接放弃
       if(strlen($left) != strlen($right))
           return strcmp($left, $right);
       //长度一致的,按照字符切分,统计,判断是否一致
       $arrleft = str_split($left);
       $arrright = str_split($right);
       $leftstat = array();
       $rightstat = array();
       foreach($arrleft as $char) {
            if(array_key_exists($char, $leftstat))
                $leftstat[$char]++;
            else
                $leftstat[$char]=0;
       }
       foreach($arrright as $char) {
            //逻辑类似
       }
       //比较两个数组的统计是否一致
       if(count(array_diff_assoc($leftstat, $rightstat)) == 0)
           return 0;
       else
           return strcmp($left, $right);
    }

    1、排序30w行的数据,使用usort + 上面cmp函数

    2、从第2行到尾遍历排序的数据,判断本行和上一行是否一致,是:输出,不是,向下走。

    大概吧。随手写的

    Antwort
    0
  • PHP中文网

    PHP中文网2017-05-16 13:04:53

    <?php
    
    /**
     * 建立 tries Tree,存储对应单词,减少存储量,加快检索速度
     * (T)代表是一个单词
     * (F)代表不是一个单词
     *
     * hi
     * his
     * is
     *     root
     *    /   \
     *  h (F)  i(F)
     *  |      |
     *  i (T)  s(T)
     *  |
     *  s (T)
     */
    class TreeNode
    {
        public $isStr;
        public $next;
    
        /**
         * TreeNode constructor.
         *
         * 字符串为 a-z 组成,所以可以直接将大小写字符,都存成小写
         * 0 - 26 对应 a - z
         */
        public function __construct()
        {
            $this->isStr = false;
            $this->next = [];
        }
    }
    
    
    ///构建Tries Tree
    class Helper
    {
        public $treeRoot;
    
        public $debug = false;///此处开启是否以字符为索引
    
        public function __construct()
        {
            $this->treeRoot = new TreeNode();
        }
    
        /**
         * @param $str
         */
        public function insert($str)
        {
            $str = strtolower($str);///将所有的字符都作为小写存储
    
            $node = $this->treeRoot;
            for ($i = 0; $i < strlen($str); ++$i) {
                $index = $this->char2index($str{$i});
    //            $index = $str{$i};
                if (empty($node->next[$index])) {
                    $node->next[$index] = new TreeNode();
                }
                $node = $node->next[$index];
            }
            $node->isStr = true;
        }
    
        private function char2index($ch)
        {
            return ($this->debug) ? $ch : intval(ord($ch) - ord('a'));
        }
    
        private function index2char($index)
        {
            return ($this->debug) ? $index : chr($index + ord('a'));
        }
    
        /**
         * 查找对应的字符串的同形词
         * @param $str
         * @return array
         */
        public function find($str)
        {
            $result = [];
    
            $str = strtolower($str);///将所有的字符都作为小写存储
    
            $nextStr = ''; ///从后向前,逐渐追加字符,查找对应的数据
            for ($i = strlen($str) - 1; $i >= 0; --$i) {
                ///这里可以设置阈值,比如当需要找的字符串长度 > 2
                /// if(strlen($nextStr) < 2) continue;
                $nextStr = $str{$i} . $nextStr;
    
                $result = array_merge($result, $this->getResult($nextStr));
            }
            return array_unique($result);
        }
    
        /**
         * 找到对应字符串开头的所有单词
         * @param $str
         * @return array
         */
        private function getResult($str)
        {
            $result = [];
            $root = $this->treeRoot;
    
            ///先找到 tries 树中,对应的节点,确定节点是否包含子节点
            for ($i = 0; $i < strlen($str); ++$i) {
                if (empty($root)) {
                    return $result;
                }
                $index = $this->char2index($str{$i});
                $root = $root->next[$index];
            }
    
            ///利用队列遍历Tries 树,实现 O(n) 检索
            $queue = new SplQueue();
    
            ///将节点,和字符起始点,记录到数据中,后续取用
            $next = ['node' => $root, 'str' => $str];
            $queue->push($next);
    
            while (!$queue->isEmpty()) {
                $next = $queue->pop();
    
                if ($next['node']->isStr) {///确定找到的是单词后,记录到结果集
                    $result[] = $next['str'];
                }
    
                ///将下一个可能的结果集数组,放入到队列中查找
                if (!empty($next['node']->next)) {
                    foreach ($next['node']->next as $index => $item) {
                        $next = ['node' => $item, 'str' => $next['str'] . $this->index2char($index)];
                        $queue->push($next);
                    }
                }
            }
            return $result;
        }
    }
    
    $helper = new Helper();
    
    $helper->insert("is");
    $helper->insert("his");
    $helper->insert("her");
    
    $helper->insert('post');
    $helper->insert('top');
    $helper->insert('stop');
    
    
    $result = $helper->find('post');
    print_r($result);
    
    $result = $helper->find('hi');
    print_r($result);
    

    Antwort
    0
  • StornierenAntwort