数据结构(C语言)例子连载(3)====文学研究助手

该博客介绍如何使用C语言实现数据结构,通过KMP算法进行模式匹配,统计英文小说中的词汇出现次数和位置行号。程序设计要求一次性读取文件并仅扫描一次文本以提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【问题描述】 
   文学研究人员要统计某篇英文小说中某些形容词的出现次数和位置.试写一个实现这一目标的文学统计表,称为"文学研究助手"

【基本要求】
     a。英文小说存在于一个文本文件中.待统计的词汇集合要一次输入完毕,即统计工作必须在程序的一次运行之后完成.程序的输出结果是每个词的出现次数和出现位置所在行的行号,格式自行设计

      b。模式匹配要基于KMP算法
       c。整个统计过程中只对小说文字扫描一次,以提高效率

【测试数据】
    以当前的源程序文件作为测试目标
【实现提示】
         约定小说中的词汇一律不跨行

【思路演示】


【代码过程】

  1。
// base.h
// ------------------- 公用的常量和类型 ----------------------------
#include < stdio.h >
#include 
< malloc.h >
#include 
< stdlib.h >
#include 
< string .h >
// 函数结果状态代码
#define     TRUE    1
#define     FALSE    0
#define     OK        1
#define     ERROR    0
#define     INFEASIBLE    -1
#define  OVERFLOW    -2    

typedef 
int     Status;                 // 函数的返回值

// ~

2。
//hstring.h
//----------------- 串的堆分配存储表示  ---------------------------
typedef struct{
    char *ch;    //若是非空串,则按串长分配存储区,否则ch为NULL
    int length;    //串长度
}HString;

//----------------- 栈的基本操作的算法实现 --------------------------------
Status StrInit(HString &T){
    //初始化串
    T.ch=NULL; T.length=0;
    return OK;
}

Status StrAssign(HString &T, char *chars){
    //生成一个其值等于串常量chars的串T
    //if(T.ch) free(T.ch);                //释放原有的串空间
    int len;  char *c;
    for(len=0, c=chars;*c;++len,++c);  //求chars的长度i;
    if(!len) {T.ch=NULL; T.length=0;}
    else{
        if( !(T.ch = (char *) malloc(len*sizeof(char) ) ))
            exit(OVERFLOW);
        for(int i=0;i<len;i++)  T.ch[i] = chars[i];
        T.ch[i]='/0';            //结尾加上/0
        T.length = len;
    }

    return OK;
}

int StrLength(HString s){
    //返回串长度
    return s.length;
}

void StrPrint(HString s){
    //打印串
    for(int i=0;i<s.length;i++)
        printf("%c",s.ch[i]);
    //printf("/t");
}

int Index(HString s,HString t, int pos){
    //返回子串t在主串s中第pos个字符之后的位置。如不存在,则返回0   
    int i=pos,j=1;
    while(i<=s.length && j<=t.length){
        if(s.ch[i-1]==t.ch[j-1])  i++,j++;
        else            i=i-j+2,j=1;
    }
    if(j>t.length) return i-t.length;
    else return 0;
}

int Next(HString s,int j){
    //KMP模式匹配的next函数
    if(j==1) return 0;

    for(int k=j-1;k>1;k--){
        for(int i=1;i<k;i++){
            if(s.ch[i-1] != s.ch[j-k+i-1])
                break;
        }
        if(i==k)  break;
    }
    return k;
}

int Index_KMP(HString s,HString t, int pos){
    //KMP算法
    int i=pos,j=1;
    while(i<=s.length && j<=t.length){
        if(j==0 || s.ch[i-1]==t.ch[j-1])   i++,j++;
        else    j=Next(t,j);
    }
    if(j>t.length) return i-t.length;
    else  return 0;
}

int IsNotCharactor(char ch){
    //判断该字符是不是字母
    return !(ch>='a'&&ch<='z' || ch>='A'&&ch<='Z');
}

int StrCount_KMP(HString s,HString t,int pos){   
    //求串t在s中出现的次数
    int i=pos,j=1;
    int count=0;
    while(i<=s.length ){
        if(j==0 || s.ch[i-1]==t.ch[j-1])   i++,j++;
        else    j=Next(t,j);
        if(j>t.length)  {
            //if(s.ch[i-1]==' '||s.ch[i-1]=='/0')        //如果下一个字符为' ',或者为串的结尾
            //    if(s.ch[i-t.length-2]==' ' || i-t.length-2<0) //并且前一个字符为' ',或者为串的开头
                if(IsNotCharactor(s.ch[i-1]) && IsNotCharactor(s.ch[i-t.length-2]))    //如果该字符串的前一和后一字符不是字母,说明找到了
                    count++;                        //次数++
            j=1;
        }
       
    }
    return count;
}

3。
// linklist.h
// -------------------- 行数据链表  --------------------------------------
typedef  struct  LRowDataElem {
    
int row;            //所在行
    int count;            //次数
}
LRowDataElem;

typedef 
struct  LRowNode
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值