【问题描述】
文学研究人员要统计某篇英文小说中某些形容词的出现次数和位置.试写一个实现这一目标的文学统计表,称为"文学研究助手"
//
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
文学研究人员要统计某篇英文小说中某些形容词的出现次数和位置.试写一个实现这一目标的文学统计表,称为"文学研究助手"
【基本要求】
a。英文小说存在于一个文本文件中.待统计的词汇集合要一次输入完毕,即统计工作必须在程序的一次运行之后完成.程序的输出结果是每个词的出现次数和出现位置所在行的行号,格式自行设计
b。模式匹配要基于KMP算法
c。整个统计过程中只对小说文字扫描一次,以提高效率
【测试数据】
以当前的源程序文件作为测试目标
【实现提示】
约定小说中的词汇一律不跨行
【思路演示】
【代码过程】

















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。







