複数文字の問い合わせを達成するために、JavaScriptのACアルゴリズム

オリジナルリンク: http://www.cnblogs.com/caoke/p/10895032.html

まず、ACオートマトンの簡単な概要:アホ - Corasickの自動化、アルゴリズムはベル研究所、有名なマルチモードマッチングアルゴリズムの1年間の出力で1975年に生まれました。この一般的な例は、いくつかの記事を与え、その後、n個の単語で与えられますが、記事に登場したどのように多くの単語を見つけるように、m個の文字が含まれています。AC自動機を知ってもらうために、そこにパターンツリー(トライ)トライとKMPパターンマッチングアルゴリズムの基礎を来ります。KMPアルゴリズムはAC機が自動マルチモード文字列マッチングアルゴリズムであり、シングルモードの文字列マッチングアルゴリズムです。

まず、原則

詳細ACオートマトンアルゴリズム「」  https://www.cnblogs.com/cmmdc/p/7337611.html

 

二つは、JavaScriptコード

//javascript实现字典树trie,简单的实现下
class TrieNode {
    constructor(value){
        this.value = value; //value为单个字符
        this.num=1;
        this.deep=0;//根节点默认0
        this.son=[];
        this.isEnd=false;
    }
    findNode(value){
        for(let i=0;i<this.son.length;i++){
            const node=this.son[i]
            if(node.value == value){
                return node;
            }
        }
        return null;
    }
}
class Trie {
    constructor(){
        this.root=new TrieNode(null);
        this.size=1;//一开始的时候只有根节点这一个节点
    }
    insert(str){
        let node=this.root;
        for(let c of str){
            let snode = node.findNode(c);
            if(snode==null){
                snode=new TrieNode(c)
                snode.deep=node.deep+1;
                node.son.push(snode);
            }else{
                snode.num++;//有N个字符串经过它
            }
            node=snode;

        }
        //如果当前的node已经是一个word,则不需要添加
        if (!node.isEnd) {
            this.size++;
            node.isEnd = true;
        }
    }
    has(str){
        let node=this.root;
        for(let c of str){
            const snode=node.findNode(c)
            if(snode){
                node=snode;
            }else{
                return false;
            }
        }
        return node.isEnd;
    }
}
//构建字典树失败指针
function build_ac_automation(root){
    root.fail=null;
    const queue=[root]
    let i=0;
    while(i<queue.length){
        const temp=queue[i];
        for(let j=0;j<temp.son.length;j++){
            const node=temp.son[j]
            if(temp===root){
                node.fail=root;
            }else{
                node.fail=temp.fail.findNode(node.value)||root;
            }
            queue.push(node);
        }
        i++
    }
}
//ac算法多字符查询
function acSearch(arr,str) {
    //生成字典树
    const tr=new Trie()
    arr.forEach(function (item) {
        tr.insert(item)
    })
    //构造字典树的失败指针
    build_ac_automation(tr.root)
    let node=tr.root;

    const data=[];
    for(let i=0;i<str.length;i++){

        let cnode=node.findNode(str[i])
        //匹配不到字符,进入失败匹配,
        while(!cnode&&node!==tr.root){
            node=node.fail;

            cnode=node.findNode(str[i])
        }
        if(cnode){
            node=cnode;
        }
        if(node.isEnd){
            data.push({
                start:i+1-node.deep,
                len:node.deep,
                str:str.substr(i+1-node.deep,node.deep),
                num:node.num,
            })
        }
    }
    return data;
}

//test
const result=acSearch(['she','shr','her','her'],'sher');
console.log(result);

/**
 * [ { start: 0, len: 3, str: 'she', num: 1 },
 { start: 1, len: 3, str: 'her', num: 2 } ]
 */

  

  

  

ます。https://www.cnblogs.com/caoke/p/10895032.htmlで再現

おすすめ

転載: blog.csdn.net/weixin_30699235/article/details/94937995