数据结构实践(三)

@TOC)

实践内容

文本文件单词的检索与计数

  1. 任务需求
    • 建立一个文本文件,统计给定单词在文本文件中出现的总次数及位置
  2. 需求分析
    • 文本文件中每个单词不包含空格且不跨行,单词由字符序列构成且区分大小写,统计给定单词在文本 文件中出现的总次数,检索输出的某个单词出现在文本中的行号、在该行中出现的位置
    • 设计数据量大的文本,进行子串的查询处理,分析算法运行的时间效率,对所有输出的匹配位置结果 进行验证,以证明算法设计和实现的正确性
    • 用朴素模式匹配算法或KMP算法实现字符串定位
    • 可正确读取,保存文本

开发环境

实现语言:Java
开发平台:IntelliJ IDEA

算法分析

(1)朴素模式匹配算法

用模板中的每个字符去与正文中的字符一一比较。比较成功返回1;比较失败,正文的下标向后移动一位,直到比较成功。如若正文的剩余字符的长度小于模板的长度还未匹配成功,则返回-1。
代码示例:

nt index(seqstring p,seqstring t) {
    int i = 0;
    int j;
    int success = 0;
    while((i<=p.length - t.length) && (!success)) {
        j = 0;
        success = 1;
        while((j < p.length) && success) {
            if(p.str[j] != t.str[i + j]) 
                success = 0;
            else 
                j ++;
        }
        i ++;
    }
    if(success) 
        return (i - 1);
    else
        return -1;
}

(2)KMP模式匹配算法

大致是因为暴力匹配浪费大量资源比如 sssssssss和ssssb直到最后一个才发现不对,若用暴力匹配法便会一直不断的回溯尝试。若采用KMP模式匹配则可以根据得到的ssss串来去避免。
比如,在简单的一次匹配失败后,我们会想将模式串尽量的右移和主串进行匹配。右移的距离在KMP算法中是如此计算的:在已经匹配的模式串子串中,找出最长的相同的前缀和后缀,然后移动使它们重叠
在第一次匹配过程中
T: a b a c a a b a c a b a c a b a a b b
W: a b a c a b
在T[5]与W[5]出现了不匹配,而T[0]T[4]是匹配的,现在T[0]T[4]就是上文中说的已经匹配的模式串子串,现在移动找出最长的相同的前缀和后缀并使他们重叠:
T: a b a c aa b a c a b a c a b a a b b
W: a b a c a b
然后在从上次匹配失败的地方进行匹配,这样就减少了匹配次数,增加了效率
代码示例、

void Getnext(int next[],String t)
{
   int j=0,k=-1;
   next[0]=-1;
   while(j<t.length-1)
   {
      if(k == -1 || t[j] == t[k])
      {
         j++;k++;
         if(t[j]==t[k])
            next[j] = next[k];
         else
            next[j] = k;
      }
      else k = next[k];
   }
}
int KMP(String s,String t)
{
   int next[MaxSize],i=0;j=0;
   Getnext(t,next);
   while(i<s.length&&j<t.length)
   {
      if(j==-1 || s[i]==t[j])
      {
         i++;
         j++;
      }
      else j=next[j];     
   }
   if(j>=t.length)
       return (i-t.length);        
   else
      return (-1);              
}

主要是Getnext方法去直到移动的距离。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值