Erlang实战建立文本索引

问题描述

为文本建立索引是文本信息处理的一个重要的任务,给定一个由英文单词构成的文件,为文件中所有单词建立索引,记录每个单词出现的行号和每行出现的次数,并将索引存入一个文件。在Erlang实战练习(六)中我强调了当时建立文本索引的时候太粗糙,一是使用了尽量规避的进程字典的方式;二是分词使用的是正则表达式,不够灵活。本文将改进我以前建立文本索引的方式,使用ETS来存储单词及其索引列表,同时拆分词使用Erlang提供的string:token模块,更加灵活和可移植性。word_index.erl文件的总体结构如下:-module(word_index). -export(). -import(re, ). -import(string,). %% start两个参数:FileIn表示要建立索引的文本文件,FileOut表示索引保存的目标文件start(FileIn,FileOut) -> {_First,Second} = file:open(FileIn,read),%% 只读打开FileIn文件 if _First =:= ok -> LineList = readFile(Second,0),%% 函数readFile/2的功能是将文本以行为单位,存入列表  %io:format("~nfile contents:~p~n",), TableID = ets:new(index,),%% ets:new创建一个“键值”搜索表,存储键值映射元祖,设置表名为index,表的类型为ordered_set  index(FileOut,LineList,TableID);%% 为文本中的每一行建立单词索引  _First =/= ok -> io:format("Open file error: file doesn't exist!") end. readFile/2函数代码如下:%% 读取文本每一行,以{Line,LineNo}为元组存入列表中readFile(S, LineNo) -> readFile(S,LineNo,[]). readFile(S, LineNo, Ret) -> UpdateLineNo = LineNo +1, OneLine = io:get_line(S,''),%% 读取文件中的一行内容 if OneLine =:= eof -> io:format("Read file EOF!"), file:close(S), lists:reverse(Ret); OneLine =/= eof -> readFile(S,UpdateLineNo, ) end. index/3函数代码如下:index(File,LineList,TableID) -> if length(LineList) =:= 0 -> ToList = ets:tab2list(TableID), io:format("index is:~n~p~n",), writeToFile(File,ToList), io:format("create index success! "); length(LineList) =/= 0 -> First = lists:nth(1,LineList), processOneLine(First,TableID), index(File,lists:delete(First, LineList), TableID) end. %% 处理一行文本processOneLine(OneLine, TableID) -> {Element, LineNo } = OneLine, %io:format("Line no:~p~n",), Words = string:tokens(Element,"nt "), matchWords(Words,LineNo,TableID). matchWords([], LineNo, TableID) -> io:format("process line(~p) success!~n",); matchWords(Words, LineNo, TableID) -> %io:format("Words:~p~n",), Word = lists:nth(1,Words), _Value = ets:lookup(TableID,Word),%%返回值为匹配Word的元组列表 if length(_Value) =:= 0 -> %% Word还未被索引,直接**入此Word索引  ets:insert(TableID,{Word,} ); length(_Value) =/= 0 -> %% Word已被索引,更新Word索引列表  KVs = lists:nth(1,_Value), Value = element(2,KVs), ets:insert(TableID,{Word, insertRec(Value,LineNo) } ) end, matchWords(lists:delete(Word, Words), LineNo, TableID). %% 处理行号与出现次数元组列表insertRec(List,LineNo) -> insertRec(List,LineNo,length(List)). insertRec(List, LineNo, 0) -> ; insertRec(List, LineNo, Ret) -> First = lists:nth(Ret,List), {LN, Num} = First, if LN =:= LineNo -> Temp = lists:delete(First, List), ; LN =/= LineNo -> insertRec(List, LineNo, Ret-1) end. %% 将索引写入文件writeToFile(File,ToList) -> {ok,S} = file:open(File,write), lists:foreach(fun(X) -> io:format(S,"~p.~n",) end, ToList), file:close(S). 至此,我已经将使用ets存储键值大型表来存储单词索引列表的程序讲完了,大家自己回去动手试验吧。本文是继续上文的一个续篇,是一种改进的建立文本索引方式。以后我还好继续通过实战练习来探讨Erlang的学习与总结思考,谢谢大家的关注。

时间: 2024-09-21 18:35:52

Erlang实战建立文本索引的相关文章

Oracle建立二进制文件索引的方法_oracle

正在看的ORACLE教程是:Oracle建立二进制文件索引的方法.Oracle text是Oracle的全文检索技术,是9i版本标准版和企业版的一部分.Oracle text使用标准的sql语言索引.查找.分析存储在oracle数据库.文件或者网络里的文本及文档. Oracle text能进行关于文档的语言分析,使用多种方法查找文档,包括关键字.上下文查询.逻辑操作.模式匹配.混合主题查询.HTML/XML段落查找等方法.Oracle text在包含文本和结构化的关系属性的混合查询方面具有优越性

Erlang实战文本排版

问题描述 文本排版大家都并不陌生,并且随处可见,无论是当前的字处理软件,如Word.PDF等,还是传统的出版行业,如:书籍.报刊.杂志等,都有良好的排版风格和样式.好的排版风格让人耳目一新,有一种继续读下去的**.本文主要是通过Erlang实现简单的文本排版,借此学习Erlang.熟悉Erlang.实战:文本排版.要求如下:**://images.51cto.com/files/uploadimg/20120508/1343260.png**://images.51cto.com/files/u

在hadoop下运用Mapreduce构建文本索引

在hadoop下运用Mapreduce构建文本索引 樊超 Hadoop是开源的一个分布式系统基础架构,借助Hadoop,可以在不了解分布式底层细节的情况下,开发分布式程序.文本索引在生产生活中有着广泛的应用,从搜索引擎的倒排索引到操作系统的指令都需要使用文本索引.在hadoop环境中构建文本索引,能够为搜索引擎和文档全文索引提供支持,并且同时兼顾了分布式系统的优点.在Hadoop环境中构建本索引的主要价值有:在分布式平台Hadoop建立倒排索引可以提高建立索引的速度,能够方便的存储大数据量,有着

MySQL建立唯一索引实现插入重复自动更新_Mysql

前言 在我们往数据库插入数据的时候,需要判断某个字段是否存在,如果存在则执行更新操作,如果不存在则执行插入操作,如果每次首先查询一次判断是否存在,再执行插入或者更新操作,就十分不方便.下面给大家分享个方法,方便大家实现这一功能,下面来一起看看吧. ON DUPLICATE KEY UPDATE 这个时候可以给这个字段(或者几个字段)建立唯一索引,同时使用以下 sql 语句进行插入或更新操作: INSERT INTO table (id, user_id, token) VALUES (NULL,

用C# 语言建立word索引,求源代码。。。

问题描述 用C# 语言建立word索引,求源代码... 各位大神,求用C# 语言建立word索引得源代码啊,急用啊.....有重谢啊.. 导入一篇word文档,自己选择关键词,然后再文档里面搜索关键字的位置,比如页码数和行数,标记下来,然后在文档的下面,显示该关键字在哪几页出现过.. 如这种形式: 解决方案 你能详细点说明你的要求吗?我有这方面的资料;你说详细点,我看看是不是你需要的,如果是你需要的就发给你 解决方案二: 我有C#与World操作的代码,可是你说的索引是怎么回事: 解决方案三:

Cassandra1.1.1建立复合主键后,如何再建立二级索引? -

最近在使用Cassandra,版本为1.1.1, CQL版本为3.0.0.遇到如下问题. 目标:利用复合主键进行查询和排序,并想利用二级索引进行多条件查询. 首先CQL建表,用到复合主键(instigator, startedAt): &http://www.aliyun.com/zixun/aggregation/37954.html">nbsp; CREATE TABLE altercations ( instigator text, startedAt text, ships

如何不用建立lucene索引的问题?

问题描述 我已经建立了对文件的索引.假如我下次查询,如何不用重新建立索引,而直接查询即是不用重新new indexwrite?? 问题补充:cloverprince 写道 解决方案 引用我的意思是,第一次建立了索引以后,下一次我访问的时候,如何不用再建立所以,直接去查询.因为发现每次调用都必须new indexwrite.时间都花费在这个地方建立索引.索引建立完,其实查询时间是很快的.不知道我表达清楚了没有?据我了解,查询和创建索引没有强制关联吧.只需要在第一次创建好索引,后面的搜索不需要再对创

mysql数据库建立组合索引原则

现实中,mysql可以根据业务需要建立组合索引,由于mysql使用B-Tree格式索引,可以直接定位记录,无需扫描.mysql建立多列索引有最左前缀的原则,即最左优先,如: 如果有一个2列的索引(col1,col2),则已经对(col1).(col1,col2)上建立了索引: 如果有一个3列索引(col1,col2,col3),则已经对(col1).(col1,col2)和(col1,col2,col3)上建立了索引: 如何建立组合索引? 最频繁使用的列放在左边: 查看列的选择性(即该列的索引值

如何用lucene给文本索引和搜索功能的应用

最近一段时间由于公司需要 ,模糊搜索出相似的关键词,所以直接考虑使用了lucene. lucene允许你往程序中添加搜索功能,lucene能够把你从文本中解析出来的数据进行索引和搜索 ,lucene不关心数据来源 甚至不关心语种,不过你需要把它转换成文本格式.也就是说你可以搜索 html网页,文本文档,word文档 ,pdf,或者其他一些 总之 只要能够提取出文本信息的即可.同样你也可以利用lucene来索引存储在数据库中的数据,以给你的用户提供一些  比如 全文搜索功能等 ,反正lucene的