백엔드 개발 PHP 튜토리얼 PHP는 검색 연관 기능을 구현합니다(사전 트리 알고리즘 기반).

PHP는 검색 연관 기능을 구현합니다(사전 트리 알고리즘 기반).

Jun 16, 2020 pm 02:28 PM
php

검색 연관 기능은 아래 그림과 같이 사용자의 입력 동작을 단순화하고 인기 검색어를 사용자에게 추천할 수 있는 기능입니다. .

PHP는 검색 연관 기능을 구현합니다(사전 트리 알고리즘 기반).

구현 원리

검색 연관 기능은 두 부분으로 나뉩니다

1. 검색어가 주어지면 해당 검색어가 붙은 다른 검색어를 찾습니다

2. 가중치가 높은 여러 쿼리 단어를 선택합니다. 이 기사에서는 첫 번째 부분의 구현에 중점을 둡니다. 여기서는 사전 트리라고도 하는 Trie 트리가 이 문제를 해결하기 위한 데이터 구조로 사용됩니다. 이 문자열이 앞에 붙은 대상 문자열은 Trie 트리를 통해 쉽고 빠르게 찾을 수 있습니다.

트라이 트리란 무엇인가요

트라이 트리, 즉 사전 트리는 단어 검색 트리 또는 키 트리라고도 알려져 있으며 트리 구조이며 해시 트리의 변형입니다. 일반적인 응용 프로그램은 많은 수의 문자열(문자열에 국한되지 않음)을 계산하고 정렬하는 데 사용되므로 검색 엔진 시스템에서 텍스트 단어 빈도 통계를 위해 자주 사용됩니다. 장점은 불필요한 문자열 비교를 최소화하고 쿼리 효율성이 해시 테이블보다 높은 경우가 많다는 것입니다.

Trie의 핵심 아이디어는 공간과 시간을 교환하는 것입니다. 문자열의 공통 접두사를 사용하면 쿼리 시간 오버헤드를 줄여 효율성을 높일 수 있습니다.

3가지 기본 속성이 있습니다:

1. 루트 노드에는 문자가 포함되지 않으며 루트 노드를 제외한 각 노드에는 문자 하나만 포함됩니다.

2. 루트 노드부터 특정 노드까지 경로를 통과하는 문자들이 연결되어 해당 노드에 해당하는 문자열을 형성합니다.

3. 각 노드의 모든 하위 노드에는 서로 다른 문자가 포함됩니다.

다음 문자열이 있다고 가정합니다

hello,hi,today,touch,weak

그러면 구성된 Trie 트리는 아래와 같습니다

PHP는 검색 연관 기능을 구현합니다(사전 트리 알고리즘 기반).질의할 때 루트에서 문자만큼 트리의 깊이만 순회하면 됩니다. 그러면 단어는 다음과 같이 될 수 있습니다. 접두사에 대한 다른 검색어를 찾으세요.

코드 구현

검색 연관 기능을 구현하는 데는 두 가지 핵심 방법이 있습니다.

1. 검색어 데이터 세트를 Trie 트리로 구성합니다.

2. 특정 검색어 단어가 앞에 붙은 모든 검색어를 찾습니다.

1단계: Trie 트리 구축

문자열에는 중국어와 영어가 있으므로 각 문자열은 다음 코드를 사용하여 분할되고 문자열은 문자 배열로 변환됩니다.

$charArray = preg_split(&#39;/(?<!^)(?!$)/u&#39;, $str);
그런 다음 각 문자열에 대해 addWordToTrieTree 메서드를 실행합니다. 이 방법은 Trie 트리에 단어를 추가합니다.

    public function buildTrieTree($strList) {
        $tree = [];
        foreach($strList as $str) {
            $charArray = preg_split(&#39;/(?<!^)(?!$)/u&#39;, $str); 
            $tree = $this->addWordToTrieTree($charArray, $tree);
        }
        return $tree;
    }
    public function addWordToTrieTree($charArray, $tree) {
        if (count($charArray) == 0) {
            return [];
        }
        $char = $charArray[0];
       
        $leftStr = array_slice($charArray, 1);
        $tree[$char] = $this->addWordToTrieTree($leftStr, $tree[$char]);
        
        return $tree;
    }

2단계: 접두어 단어 쿼리

접두어 단어를 쿼리합니다. 즉, 문자열이 주어지면 이 접두사가 붙은 모든 문자열을 쿼리합니다. 연결 과정인 트리의 문자열입니다. 먼저 findSubTree 메서드를 호출하여 Trie에서 접두사가 위치한 하위 트리를 찾은 다음 traverseTree 메서드를 호출하여 하위 트리를 순회하고 모든 문자열을 추출합니다. 여기서도 재귀적 메서드가 사용됩니다.

public function queryPrefix($prefix) {
        $charArray = preg_split(&#39;/(?<!^)(?!$)/u&#39;, $prefix);
        $subTree = $this->findSubTree($charArray, $this->tree);
        
        $words = $this->traverseTree($subTree);
        
        foreach($words as &$word) {
            $word = $prefix . $word;
        }
        return $words;
    }
    public function findSubTree($charArray, $tree) {
        foreach($charArray as $char) {
            if (in_array($char, array_keys($tree))) {
                $tree = $tree[$char];
            } else {
                return [];
            }
        }
        return $tree;
    }
    public function traverseTree($tree) {
        $words = [];
        foreach ($tree as $node => $subTree) {
            if (empty($subTree)) {
                $words[] = $node;
                return $words;
            }
            
            $chars = $this->traverseTree($subTree);
            foreach($chars as $char) {
                $words[] = $node . $char;
            }
        }
        return $words;
    }

코드 및 테스트 결과

전체 코드:

tree = $this->buildTrieTree($strList);
    }
    public function queryPrefix($prefix) {
        $charArray = preg_split(&#39;/(?<!^)(?!$)/u&#39;, $prefix);
        $subTree = $this->findSubTree($charArray, $this->tree);
        
        $words = $this->traverseTree($subTree);
        
        foreach($words as &$word) {
            $word = $prefix . $word;
        }
        return $words;
    }
    public function findSubTree($charArray, $tree) {
        foreach($charArray as $char) {
            if (in_array($char, array_keys($tree))) {
                $tree = $tree[$char];
            } else {
                return [];
            }
        }
        return $tree;
    }
    public function traverseTree($tree) {
        $words = [];
        foreach ($tree as $node => $subTree) {
            if (empty($subTree)) {
                $words[] = $node;
                return $words;
            }
            
            $chars = $this->traverseTree($subTree);
            foreach($chars as $char) {
                $words[] = $node . $char;
            }
        }
        return $words;
    }
    /**
     * 将字符串的数组构建成Trie树
     *
     * @param [array] $strList
     * @return void
     */
    public function buildTrieTree($strList) {
        $tree = [];
        foreach($strList as $str) {
            $charArray = preg_split(&#39;/(?<!^)(?!$)/u&#39;, $str); 
            $tree = $this->addWordToTrieTree($charArray, $tree);
        }
        return $tree;
    }
    /**
     * 把一个词加入到Trie树中
     *
     * @param [type] $charArray
     * @param [type] $tree
     * @return void
     */
    public function addWordToTrieTree($charArray, $tree) {
        if (count($charArray) == 0) {
            return [];
        }
        $char = $charArray[0];
       
        $leftStr = array_slice($charArray, 1);
        $tree[$char] = $this->addWordToTrieTree($leftStr, $tree[$char]);
        
        return $tree;
    }
    public function getTree() {
        return $this->tree;
    }
}
$strList = ['春风十里','春天在哪里','一百万个可能','一千年以后','后来','后来的我们','春天里','后会无期'];
$trieTree = new TrieTree($strList);
print_r($trieTree->getTree());
$prefix = '春';
$queryRes = $trieTree->queryPrefix($prefix);
print_r($queryRes);

'10마일의 봄바람', '봄은 어디에 있는가', '백만 개의 가능성', '천년 후', '나중에', '나중에'를 비교하세요. Us', 'In Spring', 'There Will Be No Time' 등의 노래 제목은 Trie 트리를 구성하고 테스트하기 위한 데이터 세트로 사용됩니다.

다음과 같은 출력 결과를 볼 수 있습니다.

트리 트리:

Array
(
    [春] => Array
        (
            [风] => Array
                (
                    [十] => Array
                        (
                            [里] => Array
                                (
                                )
                        )
                )
            [天] => Array
                (
                    [在] => Array
                        (
                            [哪] => Array
                                (
                                    [里] => Array
                                        (
                                        )
                                )
                        )
                    [里] => Array
                        (
                        )
                )
        )
    [一] => Array
        (
            [百] => Array
                (
                    [万] => Array
                        (
                            [个] => Array
                                (
                                    [可] => Array
                                        (
                                            [能] => Array
                                                (
                                                )
                                        )
                                )
                        )
                )
            [千] => Array
                (
                    [年] => Array
                        (
                            [以] => Array
                                (
                                    [后] => Array
                                        (
                                        )
                                )
                        )
                )
        )
    [后] => Array
        (
            [来] => Array
                (
                    [的] => Array
                        (
                            [我] => Array
                                (
                                    [们] => Array
                                        (
                                        )
                                )
                        )
                )
            [会] => Array
                (
                    [无] => Array
                        (
                            [期] => Array
                                (
                                )
                        )
                )
        )
)

"spring"이라는 접두어가 붙은 문자열을 쿼리합니다

Array
(
    [0] => 春风十里
    [1] => 春天在哪里
    [2] => 春天里
)

위 내용은 PHP는 검색 연관 기능을 구현합니다(사전 트리 알고리즘 기반).의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Stock Market GPT

Stock Market GPT

더 현명한 결정을 위한 AI 기반 투자 연구

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제

PHP에서 싱글 톤 패턴을 구현하는 방법은 무엇입니까? PHP에서 싱글 톤 패턴을 구현하는 방법은 무엇입니까? Sep 25, 2025 am 12:27 AM

싱글 톤 패턴은 클래스에 인스턴스가 하나만 있고 단일 객체가 데이터베이스 연결 또는 구성 관리와 같은 시스템 작동을 조정하는 시나리오에 대한 글로벌 액세스 포인트를 제공합니다. 2. 기본 구조에는 다음이 포함됩니다. 개인 정적 속성 저장 인스턴스, 개인 생성기는 외부 생성을 방지, 개인 복제 방법을 복사하지 못하고 인스턴스를 얻기위한 공개 정적 방법 (getInstance ()). 3. getInstance () 메소드를 호출하여 PHP에서 고유 한 인스턴스를 얻고 몇 번이나 호출 되더라도 동일한 개체 참조를 반환합니다. 4. 표준 PHP 요청 모델에서 스레드 안전을 고려할 필요는 없지만, 동기화 문제는 장기 또는 다중 스레드 환경에서주의를 기울여야하며 PHP 자체는 기본 잠금 메커니즘을 지원하지 않습니다. 5. 싱글 톤은 유용하지만

PHP에서 Null Coalescing 연산자 (??)을 사용하는 방법? PHP에서 Null Coalescing 연산자 (??)을 사용하는 방법? Sep 25, 2025 am 01:28 AM

답변 : PHP의 빈 합병 연산자 (??)은 변수 또는 배열 키가 존재하고 무효가 아닌지 확인하는 데 사용됩니다. 사실이라면 값을 반환하고 그렇지 않으면 기본값을 반환합니다. 긴 ISSET () 점검을 사용하는 것을 피하고, $ username = $ userInput ?? 'Guest'와 같은 정의되지 않은 변수 및 배열 키를 처리하는 데 적합하며, $ teme = $ usertheme ?? $ defaulttheme ?? 'Dark'와 같은 체인 호출을 지원합니다. 양식, 구성 및 사용자 입력에 특히 적합한 경우, emull values, emply vallys, emply values, excluds and excluds is allud valluds is allud valluds.

PHP에서 URL 매개 변수를 얻는 방법은 무엇입니까? PHP에서 URL 매개 변수를 얻는 방법은 무엇입니까? Sep 24, 2025 am 05:11 AM

$ _get을 사용하여? name = john & age = 25와 같은 URL 매개 변수를 얻습니다. ISSET 또는 빈 병합 연산자를 통해 존재를 점검하고 Filter_Input로 데이터를 필터링하고 확인하여 보안을 보장하십시오.

Manwa2 웹 버전 Direct Link_manwa2 (오스트레일리아 버전) 웹 포털 최신 업데이트 Manwa2 웹 버전 Direct Link_manwa2 (오스트레일리아 버전) 웹 포털 최신 업데이트 Sep 23, 2025 am 11:42 AM

Manwa2 웹 버전의 직접 링크는 http://www.manwaw.cn/입니다. 이 플랫폼은 수많은 고화질 만화 리소스를 제공하고 온라인 검색, 오프라인 캐시 및 다중 터미널 동기화를 지원하며 사용자의 부드럽고 편안한 만화 체이스 경험을 보장하기 위해 개인화 된 책 목록 및 읽기 설정 기능이 있습니다.

PHP에서 함수를 비활성화하는 방법은 무엇입니까? PHP에서 함수를 비활성화하는 방법은 무엇입니까? Sep 24, 2025 am 02:40 AM

TodisableAphPnect, usedisable_functionsInphp.iniforBuilt-infunctions likeExecorsystem, whathlocksthemgloballyforsecurity; foruser-definedflustions, revingexecutionswappingtheminditions, renaming, comments, orcontrollingfileinclusionviaautoloa

PHP에서 URL에서 파일을 다운로드하는 방법은 무엇입니까? PHP에서 URL에서 파일을 다운로드하는 방법은 무엇입니까? Sep 24, 2025 am 05:45 AM

답변 : File_Get_Contents 및 CURL을 사용하여 URL 파일을 다운로드하면 전자는 간단하지만 제한적이지만 후자는 더 유연하고 스트리밍을 지원합니다. 예로는 파일을 직접 읽고 쓰고 쓰기, CURL 초기화 설정 옵션 및 저장, 오류 처리 추가 및 HTTP 상태 검사가 포함됩니다. 대형 파일은 블록으로 다운로드를 스트리밍하여 메모리를 저장하여 디렉토리를 쓰고 예외를 올바르게 처리 할 수 ​​있도록 권장됩니다.

PHP 클래스에서 인터페이스를 구현하는 방법은 무엇입니까? PHP 클래스에서 인터페이스를 구현하는 방법은 무엇입니까? Sep 25, 2025 am 05:34 AM

Amplements 키워드를 사용하여 인터페이스를 구현하면 클래스는 인터페이스에서 모든 메소드의 특정 구현을 제공해야합니다. 2. 인터페이스 키워드를 사용하여 메소드를 선언하려면 인터페이스를 정의하십시오. 3. 클래스는 인터페이스를 구현하고 메소드를 무시합니다. 4. 객체를 생성하고 메소드를 호출하여 결과를 출력하십시오. 5. 클래스는 여러 인터페이스를 구현하여 코드 사양 및 유지 관리 가능성을 보장 할 수 있습니다.

PHP에서 기준으로 변수를 전달하는 방법은 무엇입니까? PHP에서 기준으로 변수를 전달하는 방법은 무엇입니까? Sep 23, 2025 am 06:47 AM

함수가 원래 변수를 직접 수정하도록 함수 매개 변수 전에 참조 전달을 구현하려면 & 기호를 사용하십시오. 예를 들어, FunctionIncrement (& $ value) {$ value;}를 정의한 후 ycrement ($ 숫자)를 호출하면 $ 숫자가 변경됩니다. 통화에서 참조 통과를 사용할 필요는 없지만 함수 선언에서만 사용하면됩니다. 또한 & function & getglobalref ()를 통해 참조를 반환 할 수 있으므로 $ ref = & getGlobalref ()가 정적 변수를 가리키고 그 값을 수정할 수 있습니다.

See all articles