基于KWIC 的关键字匹配算法(管道+过滤器模式下实现)

下面是基于KWIC 的关键字匹配算法(管道+过滤器模式下实现)

关键部分的管道+过滤器 软件体系下的实现, 在很多的关键字搜索平台都使用了这一 循环移位+排序输出的 关键字匹配算法:

具体需求如下:

1、使用管道-过滤器风格:

每个过滤器处理数据,然后将结果送至下一个过滤器,。要有数据传入,过滤器即开始工作。过滤器之间的数据共享被严格限制在管道传输

四个过滤器:

输入(Input filter):

从数据源读取输入文件,解析格式,将行写入输出管道

移位(CircularShifter filter):循环移位

排序(Alphabetizer filter):

输出(Output filter)

管道:

in_cs pipe

cs_al pipe

al_ou pile

例如:

代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace KWIC
{
    /// <summary>
    /// 管道类
    /// </summary>
    public class Pipe
    {
      List<string> word;
      public List<string> read()
        {
            return word;
        }
      public void write(List<string> word)
        { this.word = word; }
    }

    /// <summary>
    /// 管道之间的过滤器接口
    /// </summary>
    public abstract class Filter
    {

        public virtual void Transform()
        { }
    }

    /// <summary>
    /// 继承并实现实现管道接口
    /// </summary>
    public class InputFilter : Filter
    {

        public Pipe outPipe;
        public List<string> word;
        public InputFilter(List<string> word, Pipe outPipe)
        {
            this.word = word;
            this.outPipe = outPipe;
        }
        public void Transform()
        {
            outPipe.write(word);
        }
    }

    /// <summary>
    /// 继承并实现过滤器接口
    /// </summary>
    public class CircleShiftFilter : Filter
    {
        public Pipe inputPipe;
        public Pipe outPipe;
        public CircleShiftFilter(Pipe inputPipe, Pipe outPipe)
        {
            this.inputPipe = inputPipe;
            this.outPipe = outPipe;
        }
        /// <summary>
        /// 关键的循环移位函数
        /// </summary>
        public virtual void Transform()
        {
            List<string> word = inputPipe.read();

            /////////////////////////////////////////////// 补充代码,将WORD数组中字符串循环移位////////////////////////////////////////////////////////

            List<string> turned_words = new List<string>();

            // 获得每一行字符串数据
            foreach (string line in word)
            {
                // 拆分一句话
                string[] words = line.Split(' ');

                // 获取单词数
                ulong word_number = (ulong)words.LongLength;

                // 临时存储中间排序好的串
                List<string> tmp_words = new List<string>();

                tmp_words.Clear();

                tmp_words.Add(line);

                string tmp_line = "";

                for (ulong i = 0; i < word_number - 1; i++)
                {
                    // 获取上一行串
                    tmp_line = tmp_words[tmp_words.Count - 1];

                    // 获取上一行串的最后一个单词
                    string last_word = tmp_line.Split(' ')[word_number -1];

                    // 获取上一行串的除了最后一个单词之外的所有单词
                    string left_words = tmp_line.Substring(0, (tmp_line.Length -last_word.Length-1 ));

                    tmp_words.Add(last_word +" "+ left_words );
                }

                // 移除原有的串
                tmp_words.RemoveAt(0);

                // 将一句移位的串加到临时的list集合
                turned_words.AddRange(tmp_words);

            }

            // 将所有移位的串加到原来list集合
            word.AddRange(turned_words);

            /////////////////////////////////////
            outPipe.write(word); 

        }
    }

    /// <summary>
    /// 实现的排序过滤器类
    /// </summary>
    public class AlphaFilter : Filter
    {
        public Pipe inputPipe;
        public Pipe outPipe;
        public AlphaFilter(Pipe inputPipe, Pipe outPipe)
        {
            this.inputPipe = inputPipe;
            this.outPipe = outPipe;
        }

        /// <summary>
        /// 排序输出函数
        /// </summary>
        public void Transform()
        {
            List<string> word = inputPipe.read();

            ////////////////////////////////////// 补充代码,将word数组中单词排序输出/////////////////////////////////////////////////
            word.Sort();

            outPipe.write(word); 

        }
    }

    /// <summary>
    /// 实现输出过滤器接口类
    /// </summary>
    public class OutputFilter : Filter
    {
        public Pipe inputPipe;
        public Pipe outPipe;
        public OutputFilter(Pipe inputPipe, Pipe outPipe)
        {
            this.inputPipe = inputPipe; this.outPipe = outPipe;

        }
        public  void Transform()
        {
            List<string> word = inputPipe.read();
            outPipe.write(word);
        }
    }

    /// <summary>
    /// 程序的整体运行框架
    /// </summary>
    public class KWIC_System
    {

        Pipe in_cs; // create three objects of Pipe
        Pipe cs_al; // and one object of type
        Pipe al_ou; // FileInputStream
        Pipe ou_ui; // FileInputStream
        InputFilter inputFilter;
        CircleShiftFilter shifter;
        AlphaFilter alpha;
        OutputFilter output; // output to screen
      public   KWIC_System()
        {
            in_cs = new Pipe(); // create three objects of Pipe
            cs_al = new Pipe(); // and one object of type
            al_ou = new Pipe(); // FileInputStream
            ou_ui = new Pipe(); // FileInputStream

            List<string> word = new List<string>();
	    word.Add(Regex.Replace("I love you".Trim(), @"\s+", " ")); //正则会获取到所有类型的空格(比如制表符,新行等等),然后将其替换为一个空格
            word.Add(Regex.Replace("me too".Trim(), @"\s+", " "));
            word.Add(Regex.Replace("do you know".Trim(), @"\s+", " "));  

            inputFilter = new InputFilter(word, in_cs);
            shifter = new CircleShiftFilter(in_cs, cs_al);
            alpha = new AlphaFilter(cs_al, al_ou);
            output = new OutputFilter(al_ou,ou_ui); // output to screen
        }
        public List<string > GetResult()
        {
            inputFilter.Transform();
            shifter.Transform();
            alpha.Transform();
            output.Transform();

            return ou_ui.read();
        }

    }

}

(备注:如果想换行这里想换行输出,需要在结尾输出的每一行结尾加‘\r\n’)

在广泛的搜索技术中,其实这个关键字匹配算法应用范围很广,比如我们常见的Baidu和Google的搜索关键字 提示功能。



基于KWIC 的关键字匹配算法(管道+过滤器模式下实现)

时间: 2024-12-25 01:39:21

基于KWIC 的关键字匹配算法(管道+过滤器模式下实现)的相关文章

软件架构模式之管道-过滤器模式--分析

在管道-过滤器架构模式中,每个构件都有一组输入,输出,构件读取输入的数据流,经过内部处理后,产生输出数据流,该过程主要完成输入流的变换及增量计算.这里的构件就是过滤器,而连接过滤器的就是管道,这个管道将上一个过滤器处理的结果数据流传送到下一个过滤器,在进行其他的计算. 简单来说,管道-过滤器模式结构就像是一条产品加工流水线,原材料在流水线上经过一个个工人的加工,最终生产出产品.这里的工人就是过滤器,将材料进行加工,流水线中的传送带就是管道,将一个工人加工过得材料传送给下一个工人继续加工. 应用场

管道-过滤器模式

如果项目中的功能要求需要经过一系列的处理.可以采用管道-过滤器模式组织这些处理.每一个处理就是一个过滤器.组织过滤器的管线对象就是管道. 管道模式适用于一系列确定/已知的步骤处理. 原始的管道模型可以像下面这样: /// <summary> /// 处理消息 /// </summary> public abstract class Context { } /// <summary> /// 过滤器 /// </summary> /// <typepar

基于容器的持续交付管道

基于容器的持续交付管道 在过去的几篇d4d系列中,我给大家介绍了如何使用docker来支持asp.net core的应用开发,打包的场景.Asp.net core的跨平台开发能力为.net开发人员提供了使用容器进行应用开发的能力,今天这篇文章将对如何使用微软的全生命周期管理平台VSTS/TFS来构建基于容器的CI/CD管道来支持团队开发的场景. #1 前世今生 & 世界你好#2 容器化主机#3 在macOS上使用Visual Studio Code和Docker开发asp.net core和my

【设计模式】过滤器模式

过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来.这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准. 实现 我们将创建一个 Person 对象.Criteria 接口和实现了该接口的实体类,来过滤 Person 对象的列表.CriteriaPatternDemo,我们的演示类使用 Criteria 对象,基于各种标准和它们的结合来过滤 Pe

docker4dotnet #5 使用VSTS/TFS搭建基于容器的持续交付管道

在过去的几篇d4d系列中,我给大家介绍了如何使用docker来支持asp.net core的应用开发,打包的场景.Asp.net core的跨平台开发能力为.net开发人员提供了使用容器进行应用开发的能力,今天这篇文章将对如何使用微软的全生命周期管理平台VSTS/TFS来构建基于容器的CI/CD管道来支持团队开发的场景. #1 前世今生 & 世界你好#2 容器化主机#3 在macOS上使用Visual Studio Code和Docker开发asp.net core和mysql应用#4 使用Az

Java多线程编程实战指南(设计模式篇,黄文海)-之管道线模式

不得不说,本人工作上很少有使用多线程编程技术的地方.由于本人工作上经常使用的是类似SSH等框架搭建MVC架构,所以更加习惯于编写一些优秀程序员所唾弃的样板式的代码.最近看了文海的多线程编程实战指南,瞬间眼前一亮.觉得有很多自己可以学习的,事实上,我已经在最近的项目中使用上了那本书介绍的两相终止模式.串行封闭模式.生产者消费者模式以及线程池等技术,确实在许多方面改进了我们服务端的吞吐量.说到这里本人吐槽一下,由于是毕业后转行,目前也才工作一年还不满2个月.所以原谅我的得瑟,但我相信我以后会做的更好

设计模式(27)-----结构型模式-----过滤器模式

过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来.这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准. 实现 我们将创建一个 Person 对象.Criteria 接口和实现了该接口的实体类,来过滤 Person 对象的列表.CriteriaPatternDemo,我们的演示类使用 Criteria 对象,基于各种标准和它们的结合来过滤 Pe

检测到在集成的托管管道模式下不适用的 ASP.NET 设置。

我们将ASP.NET程序从IIS6移植到IIS7,可能运行提示以下错误: HTTP 错误 500.23 - Internal Server Error 检测到在集成的托管管道模式下不适用的 ASP.NET 设置. 为什么会出现以上错误? 在IIS7的应用程序池有两种模式,一种是“集成模式”,一种是“经典模式”. 经典模式 则是我们以前习惯的IIS 6 的方式. 如果使用集成模式,那么对自定义的httpModules 和 httpHandlers 就要修改配置文件,需要将他们转移到<modules

基于灰度的模板匹配算法(三):划分强度一致法(PIU)

简介: 前面几篇文章介绍了一些比较基本的基于灰度的图像配准算法: 基于灰度的模板匹配算法(一):MAD.SAD.SSD.MSD.NCC.SSDA.SATD算法  基于灰度的模板匹配算法(二):局部灰度值编码  基于互信息的图像配准算法:MI.EMI.ECC算法  本文将介绍一种类似的相似度测量算法,叫做划分强度一致法(Partitioned Intensity Uniformity,PIU). PIU算法:         1992年,Woods提出了基于划分强度一致的MR-PET图像配准.在医