数据结构与算法 -- 字符串匹配

1、Trie树

public class TrieTree {
    private TrieNode root = new TrieNode(‘/‘);//存储无意义字符

    //往Trie树中插入一个字符串
    public void insert(char[] text) {
        TrieNode p = root;
        for(int i=0; i<text.length; i++) {
            int index = text[i] - ‘a‘;
            if(p.children[index] == null) {
                TrieNode newNode = new TrieNode(text[i]);
                p.children[index] = newNode;
            }
            p = p.children[index];
        }
        p.isEndingChar = true;
    }

    //在Trie树中查找一个字符串
    public boolean find(char[] pattern) {
        TrieNode p = root;
        for(int i=0; i<pattern.length; i++) {
            int index = pattern[i] - ‘a‘;
            if(p.children[index] == null) {
                return false;//不存在pattern
            }
            p = p.children[index];
        }
        if(p.isEndingChar) {//完全匹配到pattern
            return true;
        }else {//不能完全匹配,只是前缀
            return false;
        }
    }
    public class TrieNode{
        public char data;
        public TrieNode[] children = new TrieNode[26];
        public boolean isEndingChar = false;
        public TrieNode(char data) {
            this.data = data;
        }
    }

    public static void main(String[] args) {
        TrieTree trieTree = new TrieTree();
        trieTree.insert("hello".toCharArray());
        trieTree.insert("world".toCharArray());
        trieTree.insert("word".toCharArray());
        trieTree.insert("teacher".toCharArray());
        trieTree.insert("wild".toCharArray());
        String pattern = "word";
        System.out.println(trieTree.find(pattern.toCharArray()) ? "找到了 " + pattern : "没有完全匹配的字符串 " + pattern);
        pattern = "wor";
        System.out.println(trieTree.find(pattern.toCharArray()) ? "找到了 " + pattern : "没有完全匹配的字符串 " + pattern);
    }
}

2、利用Trie树实现搜索引擎的搜索关键词提示功能

import java.util.ArrayList;
import java.util.List;

public class TrieTree {
    private TrieNode root = new TrieNode(‘/‘);//存储无意义字符

    //往Trie树中插入一个字符串
    public void insert(char[] text) {
        TrieNode p = root;
        for(int i=0; i<text.length; i++) {
            int index = text[i] - ‘a‘;
            if(p.children[index] == null) {
                TrieNode newNode = new TrieNode(text[i]);
                p.children[index] = newNode;
            }
            p = p.children[index];
        }
        p.isEndingChar = true;
    }

    //在Trie树中查找一个字符串
    public List<String> find(char[] pattern) {
        TrieNode p = root;
        for(int i=0; i<pattern.length; i++) {
            int index = pattern[i] - ‘a‘;
            if(p.children[index] == null) {
                return dfsResult;//不存在pattern
            }
            p = p.children[index];
        }
        if(p.isEndingChar) {//完全匹配到pattern
            dfsResult.add(new String(pattern));
            return dfsResult;
        }else {//不能完全匹配,只是前缀
            String startPath = new String(pattern);
            //模式串 pattern的最后一个字符保存在p中,所以传入的path去掉该字符
            dfs(p, new StringBuffer(startPath.substring(0, startPath.length()-1)));
            return dfsResult;
        }
    }

    private List<String> dfsResult = new ArrayList<String>();
    private void dfs(TrieNode p, StringBuffer path) {
        if(p.isEndingChar) {
            dfsResult.add(new String(path.append(p.data).toString()));
        }else {
            for(int j=0; j<26; j++) {
                if(p.children[j] != null) {
                    StringBuffer pathCopy = new StringBuffer(path.toString());
                    dfs(p.children[j], pathCopy.append(p.data));
                }
            }
        }
    }
    public class TrieNode{
        public char data;
        public TrieNode[] children = new TrieNode[26];
        public boolean isEndingChar = false;
        public TrieNode(char data) {
            this.data = data;
        }
    }

    public static void main(String[] args) {
        TrieTree trieTree = new TrieTree();
        trieTree.insert("hello".toCharArray());
        trieTree.insert("world".toCharArray());
        trieTree.insert("word".toCharArray());
        trieTree.insert("teacher".toCharArray());
        trieTree.insert("wild".toCharArray());
        String pattern = "w";
        List<String> findResult = trieTree.find(pattern.toCharArray());
        for(String item : findResult) {
            System.out.println(item);
        }
        System.out.println("------------------");

        trieTree.dfsResult.clear();
        pattern = "wor";
        findResult = trieTree.find(pattern.toCharArray());
        for(String item : findResult) {
            System.out.println(item);
        }
        System.out.println("------------------");

        trieTree.dfsResult.clear();
        pattern = "word";
        findResult = trieTree.find(pattern.toCharArray());
        for(String item : findResult) {
            System.out.println(item);
        }
        System.out.println("------------------");
    }
}

原文地址:https://www.cnblogs.com/jiangwangxiang/p/11106262.html

时间: 2024-10-03 22:43:48

数据结构与算法 -- 字符串匹配的相关文章

算法——字符串匹配之KMP算法

前言 本节介绍Knuth-Morris-Pratt字符串匹配算法(简称KMP算法).该算法最主要是构造出模式串pat的前缀和后缀的最大相同字符串长度数组next,和前面介绍的<朴素字符串匹配算法>不同,朴素算法是当遇到不匹配字符时,向后移动一位继续匹配,而KMP算法是当遇到不匹配字符时,不是简单的向后移一位字符,而是根据前面已匹配的字符数和模式串前缀和后缀的最大相同字符串长度数组next的元素来确定向后移动的位数,所以KMP算法的时间复杂度比朴素算法的要少,并且是线性时间复杂度,即预处理时间复

数据结构之 字符串---字符串匹配(kmp算法)

串结构练习——字符串匹配 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定两个字符串string1和string2,判断string2是否为string1的子串. 输入 输入包含多组数据,每组测试数据包含两行,第一行代表string1,第二行代表string2,string1和string2中保证不出现空格. 输出 对于每组输入数据,若string2是string1的子串,则输出"YES",否则输出"NO". 示例输入

算法——字符串匹配之BM算法

前言 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法(简称BM算法),后缀匹配就是模式串从右到左开始比较,但模式串的移动依然是从左到右的.在实践中,BM算法效率高于前面介绍的<KMP算法>,算法分为两个阶段:预处理阶段和搜索阶段:预处理阶段时间和空间复杂度都是是O(m+sigma),sigma是字符集大小,一般为256:在最坏的情况下算法时间复杂度是O(m*n):在最好的情况下达到O(n/m). BM算法实现 BM算法预处理过程 BM算法有两个规则分别为坏字符规则(Bad Cha

KMP算法字符串匹配

对于暴力搜索法,当搜索词对应的字符与字符串中的字符不匹配时.将搜索词整个后移一位,再从头逐个比较.这样做虽然可行,但是效率很差,因为你要把"搜索位置"移到已经比较过的位置,重比一遍. 应用KMP算法之后,则有: 移动位数=已匹配的字符数?对应的部分匹配值 "部分匹配值"就是"前缀"和"后缀"的最长的共有元素的长度. KMP算法实现代码如下: void prefixFun(char *pattern, int *preFun)

算法——字符串匹配之有限自动机算法

前言 上篇文章介绍<Rabin-Karp字符串匹配算法>,这里介绍有限自动机(Finite Automata)字符串匹配算法,有限自动机(Finite Automata)字符串匹配算法最主要的是计算出转移函数.即给定一个当前状态k和一个字符x,计算下一个状态:计算方法为:找出模式pat的最长前缀prefix,同时也是pat[0...k-1]x(注意:字符串下标是从0开始)的后缀,则prefix的长度即为下一个状态.匹配的过程是比较输入文本子串和模式串的状态值,若相等则存在,若不想等则不存在.有

算法——字符串匹配之Rabin-Karp算法

前言 Rabin-Karp字符串匹配算法和前面介绍的<朴素字符串匹配算法>类似,也是对应每一个字符进行比较,不同的是Rabin-Karp采用了把字符进行预处理,也就是对每个字符进行对应进制数并取模运算,类似于通过某种函数计算其函数值,比较的是每个字符的函数值.预处理时间O(m),匹配时间是O((n-m+1)m). Rabin-Karp算法实现 伪代码: Rabin_Karp_search(T, P, d, q) n = T.length; m = P.length; h = d^(m-1)mo

Horspool算法-字符串匹配

不得不说ACM哪怕是没有结果,对于算法能力的训练是毋庸置疑的-- 因为老师划了重点,所以讲一下horspool的字符串匹配算法的原理吧. 先声明几个概念,被找的字符串称为匹配串,要找的字符串被称为模式串,当前和模式串相匹配的匹配串的子串被称为匹配子串(废话 在朴素算法中,我们要找一个匹配串是否存在模式串,例如HuangZhi is a genius的匹配串串和ChengJinSen的模式串,那么我们一开始用的方法是用: HuangZhi is(11 character) 去匹配: ChengJi

KMP算法---字符串匹配

算法细节详见点击打开链接和点击打开链接 #include <stdio.h> #include <stdlib.h> #define N 7 #define M 15 void showpset(int* a); void cal_pset(char* a, int* p,int n); int KMP(char* a,char* b,int* P); int main(void) { char a[M]={'a','b','a','c','a','b','a','a','b','

KMP算法 - 字符串匹配的简单运用 --- HDU 1711

Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11606    Accepted Submission(s): 5294 Problem Description Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b