WM多模式字符串匹配

13 篇文章 0 订阅
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace WMCSharp
{
        //++++++++++++++++++++++++++++++++++++++//
        //   保存敏感词前缀及所有前缀相同的词   //
        //++++++++++++++++++++++++++++++++++++++//
        class Node
        {
            public ArrayList str;
            public string strpre;
            public Node() { str = new ArrayList(); strpre = null; }
        };
        //++++++++++++++++++++++++++++++++++++++//
        // 前缀表的建立、查找及完整字符串的匹配 //
        //++++++++++++++++++++++++++++++++++++++//
        class PreNode : Node
        {
            const int NODE_NUM = 100;
            public Node[] pre = new Node[NODE_NUM];
            public PreNode()
            {
                for (int i = 0; i < NODE_NUM; i++)
                {
                    pre[i] = new Node();


                }
            }
            //**************************************//
            //             匹配完整字符串           //
            //**************************************//
            public ArrayList  searchrstr(string str, int n, int len_mi, ArrayList  result)
            {
                int length = 24;   //敏感词最大长度
                int breakcount = 0;   //
                if (length > str.Length)
                    length = str.Length;
                for (int i = len_mi; i <= length; i++)
                {
                    if (breakcount > pre[n].str.Count)    //如果表以经遍历一遍,则跳出。
                        break;
                    string ss = str.Substring(0, i);
                    if (pre[n].str.Contains(ss))
                    {
                        breakcount++;
                        Console.WriteLine(ss);
                        result.Add(ss);
                    }
                }
                return result;
            }
            //**************************************//
            //               插入前缀               //
            //**************************************//
            public void insertpre(string str, int len = 2)
            {
                string ss = str.Substring(0, len);
                int i = 0;
                while (pre[i].strpre != null)
                    if (!pre[i].strpre.Equals(ss))
                        i++;
                    else
                        break;
                pre[i].strpre = ss.Substring(0, ss.Length);
                pre[i].str.Add(str);


            }
            //**************************************//
            //           按前缀查找                 //
            //**************************************//
            public int serchpre(string str)
            {
                int i = 0;
                while (i < NODE_NUM)
                {
                    if (pre[i].strpre == null)
                        return -1;
                    if (pre[i].strpre.Equals(str))
                        return i;
                    i++;
                }
                return -1;
            }
        }
        //++++++++++++++++++++++++++++++++++++++//
        //              WM算法                  //
        //++++++++++++++++++++++++++++++++++++++//
        class WM
        {
            int len_min = 128;   
            int COUNT = 0;
            private int[] Shift;
            PreNode[] ArrPre ;
            Hashtable str_Block = new Hashtable();
            //**************************************//
            //   初始化函数,建立Shift表,前缀表    //
            //**************************************//
            public int init(string FilePath)    //参数为敏感词 文件路径+文件名
            {
                ArrayList str = new ArrayList();
                if (!System.IO.File.Exists(FilePath))
                {
                    Console.WriteLine("词库不存在!");
                    return 0;
                } 
                StreamReader f2 = new StreamReader(FilePath, System.Text.Encoding.GetEncoding("gb2312"));               
                while (!f2.EndOfStream)    
                {                    
                    str.Add(f2.ReadLine());
                }
                f2.Close();
                int n  = str.Count;    
                for (int i = 0; i < n; i++)          //获取最短敏感词长度
                {
                    if (len_min > str[i].ToString().Length)
                        len_min = str[i].ToString().Length;
                }
                if (len_min < 2)
                {
                    Console.WriteLine("词库不允许有单字存在!");
                    return 0;                
                }
                ArrPre = new PreNode[n];  //初始化前缀表的大小 
                Shift = new int[n];      //初始化Shift表的大小
                for (int i = 0; i < n ; i++) //初始化Shift表
                {
                    Shift[i] = -1;
                    ArrPre[i] = new PreNode();
                }


               
                int block_value = -1;
                for (int i = 0; i < n; i++)         //建立Shif表,前缀表,和词表
                {
                    string term = str[i].ToString().Substring(0);
                    int ndx = 0;
                    while (ndx++ < len_min - 1)
                    {
                        string Block = term.Substring(ndx - 1, 2);
                        if (!str_Block.ContainsKey(Block))
                        {
                            str_Block.Add(Block, COUNT);
                            Shift[COUNT++] = len_min - ndx - 1;
                            if (Shift[COUNT - 1] == 0)
                                if (ArrPre[COUNT - 1] != null)
                                    ArrPre[COUNT - 1].insertpre(term, len_min);
                            continue;
                        }
                        else
                        {
                            block_value = (int)str_Block[Block];
                            if (Shift[block_value] > len_min - ndx - 1 || (len_min - ndx - 1) == 0)
                            {
                                Shift[block_value] = len_min - ndx - 1;
                                if (Shift[block_value] == 0)
                                    ArrPre[block_value].insertpre(term, len_min);
                                continue;
                            }
                            continue;
                        }
                    }
                }
                return 1;
            }
            //**************************************//
            //    查找函数,结果保存在ArrayList中   //
            //**************************************//
            public ArrayList  Search(string text, ArrayList  result) 
            {
                ArrayList error = new ArrayList();
                if (text == null)
                {
                    error.Add("The text is null!");
                    return error;
                }
                int len = len_min;
                int len_text = text.Length;
                char[] p = text.ToArray();
                char[] block = new char[2];
                int i = 0;
                while (len_text > i)
                {
                    block[0] = p[i++];
                    if (i == len_text)
                    {
                        break;
                    }
                    block[1] = p[i++];
                    i--; i--;
                    string Block = new string(block);
                    if (!str_Block.ContainsKey(Block))
                    {
                        i++;
                        continue;
                    }
                    int step = Shift[(int)str_Block[Block]];
                    if (step > 0)
                    {
                        while (step-- > 0)
                            i++;
                        continue;
                    }
                    if (step == 0)
                    {
                        i++;
                        string stemp = text.Substring(i + 1 - len, len);
                        int k = (int)str_Block[Block];
                        int pos = ArrPre[k].serchpre(stemp);
                        if (pos != -1)
                        {
                            string strtemp = text.Substring(i + 1 - len);
                            result = ArrPre[k].searchrstr(strtemp, pos, len, result);
                        }
                    }
                }
                return result;
            }
        }    
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WM算法是一种字符串匹配算法,其全称是"Shift-And算法",也称为"Bitap算法"。该算法通过将模式串的每个字符用二进制表示,然后将这些二进制数构成一个二维矩阵,再通过按列计算的方法,将模式串的匹配转换为矩阵的匹配。在匹配的过程中,算法通过移位和与操作来快速地判断文本串中是否存在与模式串匹配的子串。 具体来说,WM算法的匹配过程分为两个步骤: 1. 预处理模式串,生成一个二维矩阵,每一列代表一个字符,每一行代表一个二进制位。矩阵中的第i行第j列的值为1,当且仅当模式串中第j个字符的二进制表示的第i位为1。 2. 在文本串中按列计算,将文本串中每个字符的二进制表示与模式串的矩阵进行"与"操作,然后将结果向左移位。如果某一列的结果等于0,则表示在文本串中不存在与该列匹配的字符。如果某一列的结果包含1,则表示在文本串中可能存在与该列匹配的字符。通过对每一列进行"与"操作和移位,最终可以得到文本串中所有可能与模式串匹配的位置。 WM算法的时间复杂度为O(mn/w),其中m为模式串的长度,n为文本串的长度,w为计算机中一个字(word)的位数。相比于其他的字符串匹配算法WM算法的优点在于:不需要使用哈希函数,可以适用于任何字符集,且可以处理模式串中包含通配符的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值