文本文件单词的检索与计数Word文档下载推荐.docx
- 文档编号:16263331
- 上传时间:2022-11-22
- 格式:DOCX
- 页数:15
- 大小:117.42KB
文本文件单词的检索与计数Word文档下载推荐.docx
《文本文件单词的检索与计数Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《文本文件单词的检索与计数Word文档下载推荐.docx(15页珍藏版)》请在冰豆网上搜索。
(用C或C++语言描述)
详细设计
朴素模式匹配算法
该算法的基本思想是:
设有三个指针——i,j,k,用i指示主串S每次开始比较的位置;
指针j,k分别指示主串S和模式串T中当前正在等待比较的字符位置;
一开始从主串S的第一个字符(i=0;
j=1)和模式T的第一个字符(k=0)比较,若相等,则继续逐个比较后续字符(j++,k++)。
否则从主串的下一个字符(i++)起再重新和模式串(j=0)的字符开始比较。
依此类推,直到模式T中的所有字符都比较完,而且一直相等,则称匹配成功,并返回位置i;
否则返回-1,表示匹配失败。
顺序串的模式匹配算法如下:
intindex(SStringS,SStringT)
{//求子串T在主串S中首次出现的位置
inti,j,k,m,n;
m=T.length;
//模式串长度赋m
n=S.length;
//目标串长度赋n
for(i=0;
i<
=n-m;
i++)
{
j=0;
k=i;
//目标串起始位置i送入k
while(j<
=m&
&
s.ch[k]==t.ch[j])
{k++;
j++;
}//继续下一个字符的比较
if(j==m)//若相等,则说明找到匹配的子串,返回匹配位置i,
//否则从下一个位置重新开始比较
returni;
}//endfor
return-1;
}//endIndex
给定位置的串匹配算法
该算法要求从串S1(为顺序存储结构)中第k个字符起,求出首次与字符串S2相同的子串的起始位置。
该算法与上面介绍的模式匹配算法类似,只不过上述算法的要求是从主串的第一个字符开始,该算法是上述算法的另一种思路:
从第k个元素开始扫描S1,当其元素值与S2的第一个元素的值相同时,判定它们之后的元素值是否依次相同,直到S2结束为止。
若都相同,则返回当前位置值;
否则继续上述过程,直至S1扫描完为止,其实现算法如下:
IntPartPosition(SStringS1,SStringS2,intk)
{
inti,j;
i=k-1;
//扫描s1的下标,因为c中数组下标是从0开始,串中序号相差1
j=0;
//扫描s2的开始下标
while(i<
s1.length&
j<
s2.length)
if(s1.ch[i]==s2.ch[j])
{i++;
//继续使下标移向下一个字符位置}
else
{i=i-j+1;
//使i下标回溯到原位置的下一个位置,使j指向s2的第一个字符,再重新比较}
if(j>
=s2.length)
returni-s2.length;
//表示s1中存在s2,返回其起始位置
return-1;
//表示s1中不存在s2,返回-1
}//函数结束
说明:
以上两个算法可统一为一个算法,即在子串定位算法Index(S,T)的参数中增加一个起始位置参数即可。
建立文本文件
建立文件的实现思路是:
(1)定义一个串变量;
(2)定义文本文件;
(3)输入文件名,打开该文件;
(4)循环读入文本行,写入文本文件,其过程如下:
While(
不是文件输入结束){
读入一文本行至串变量;
串变量写入文件;
输入是否结束输入标志;
}
(5)关闭文件。
给定单词的计数
该功能需要用到前一节中设计的模式匹配算法,逐行扫描文本文件。
匹配一个,计数器加1,直到整个文件扫描结束;
然后输出单词出现的次数。
其实现过程如下:
(1)输入要检索的文本文件名,打开相应的文件;
(2)输入要检索统计的单词;
(3)循环读文本文件,读入一行,将其送入定义好的串中,并求该串的实际长度,调用串匹配函数进行计数。
具体描述如下:
While(不是文件结束){
读入一行并到串中;
求出串长度;
模式匹配函数计数;
(4)关闭文件,输出统计结果。
检索单词出现在文本文件中的行号、次数及其位置
这个设计要求与上一个类似,但要相对复杂一些。
其实现过程描述如下:
(3)行计数器置初值0;
(4)while(不是文件结束){
读入一行到指定串中;
行单词计数器置0;
调用模式匹配函数匹配单词定位、该行匹配单词计数;
行号计数器加1;
If(行单词计数器!
=0)
输出行号、该行有匹配单词的个数以及相应的位置;
运行主控程序
主控菜单程序的结构要求内容如下:
(1)头文件包含;
(2)菜单选项包括:
1.建立文件
2.单词计数
3.单词定位
4.退出程序
(3)选择1——4执行相应的操作,其他字符为非法。
程序代码:
#include<
stdio.h>
stdlib.h>
string.h>
#defineLIST_INIT_SIZE500/*线性表存储空间的初始分配量*/
#defineLISTINCREMENT10/*线性表存储空间的分配增量*/
#defineFILE_NAME_LEN20/*文件名长度*/
#defineWORD_LEN20/*单词长度*/
#defineMaxStrSize256
#definellength110/*规定一行有110个字节*/
typedefstruct{
charch[MaxStr];
/*ch是一个可容纳256个字符的字符数组*/
intlength;
}string;
/*定义顺序串类型*/
charword[WORD];
/*存储单词,不超过20个字符*/
intcount;
/*单词出现的次数*/
}elem_type;
typedefstruct{
elem_type*elem;
/*存储空间基址*/
/*当前长度*/
intlistsize;
/*当前分配的存储容量*/
}sqlist;
voidsqlist_init(sqlist*sq,elem_type*et){
sq->
elem=et;
length=0;
voidsqlist_add(sqlist*sq,elem_type*et,char*word)
inti;
intj;
for(i=0;
i<
length;
/*当前单词与加入的单词相同,直接统计,不做插入*/
if(strcmp(et[i].word,word)==0)
et[i].count++;
return;
}
if(strcmp(et[i].word,word)>
0)
break;
if(sq->
length==LIST_INIT_SIZE)
printf("
空间不足,单词[%s]插入失败\n"
word);
return;
for(j=sq->
j>
i;
j--)
memcpy(et+j,et+j-1,sizeof(elem_type));
length++;
strcpy(et[i].word,word);
et[i].count=1;
intsqlist_count(sqlist*sq,elem_type*et)
intj=0;
for(i=0;
i<
sq->
i++)
j=j+et[i].count;
returnj;
voidcreat_text_file()
elem_typew;
sqlists;
charfile_name[FILE_NAME_LEN+1],yn;
FILE*fp;
输入要建立的文件名:
"
);
scanf("
%s"
file_name);
fp=fopen(file_name,"
w"
yn='
n'
;
/*输入结束标志初值*/
while(yn=='
||yn=='
N'
)
请输入一行文本:
gets(w.word);
s.length=strlen(w.word);
fwrite(&
w,s.length,1,fp);
fprintf(fp,"
%c"
10);
/*是输入换行*/
结束输入吗?
yorn:
yn=getchar();
fclose(fp);
/*关闭文件*/
建立文件结束!
\n"
voidsubstrsum()
charfile_name[FILE_NAME_LEN+1];
charword[WORD_LEN+1];
intj,q=0;
intw,x,y=0;
elem_typeet[LIST_INIT_SIZE];
sqlistsq;
sqlist_init(&
sq,et);
请输入文件名:
file_name);
fp=fopen(file_name,"
r"
if(fp==NULL){
打开文件失败!
while(fscanf(fp,"
word)!
=EOF){
sqlist_add(&
sq,et,word);
>
单词<
<
个数<
sq.length;
x=strlen(et[i].word);
for(w=x-1;
w>
=0;
w--)
if(et[i].word[w]<
65||(et[i].word[w]>
90&
et[i].word[w]<
97)||et[i].word[w]>
122)
et[i].word[w]='
'
for(w=0;
w<
x;
w++)
if(et[i].word[w]=='
)
y++;
if(y==x)
et[i].count=0;
y=0;
elsey=0;
if(et[i].count!
%20s%10d\n"
et[i].word,et[i].count);
elseq++;
j=sqlist_count(&
\n>
%s的单词总数为%d个\n"
file_name,j);
%s的非单词个数为%d种\n"
file_name,q);
intpartposition(strings1,strings2,intk)
{inti,j;
i=k-1;
/*扫描s1的下标,因为c中数组下标是从0开始,串中序号相差1*/
/*扫描s2的开始下标*/
while(i<
{if(s1.ch[i]==s2.ch[j])
{i++;
j++;
/*继续使下标移向下一个字符位置*/
else
i=i-j+1;
}}
if(j>
returni-s2.length;
/*表示s1中不存在s2,返回-1*/
/*表示s1中存在s2,返回其起始位置*/
}/*函数结束*/
voidsubstrcount()
strings,t;
/*定义两个串变量*/
charfname[10];
inti=0,j,k;
输入文本文件名:
fname);
fp=fopen(fname,"
输入要统计计数的单词:
t.ch);
t.length=strlen(t.ch);
while(!
feof(fp)){
memset(s.ch,'
\0'
110);
fgets(s.ch,110,fp);
s.length=strlen(s.ch);
k=0;
/*初始化开始检索位置*/
while(k<
s.length-1)/*检索整个主串S*/
j=partposition(s,t,k);
/*调用串匹配函数*/
if(j<
0)break;
else{
i++;
/*单词计数器加1*/
k=j+t.length;
/*继续下一字串的检索*/
\n单词%s在文本文件%s中共出现%d次\n"
t.ch,fname,i);
}/*统计单词出现的个数*/
voidsubstrint()
{
/*定义两个串变量*/
inti,j,k,l,m;
intwz[20];
/*存放一行中字串匹配的多个位置*/
输入要检索的单词:
l=0;
/*行计数器置0*/
feof(fp))
{/*扫描整个文本文件*/
l++;
/*行计数器自增1*/
/*初始化开始检索位置*/
i=0;
/*初始化单词计数器*/
/*调用串匹配函数*/
0)break;
else
wz[i]=j;
/*记录匹配单词位置*/
/*继续下一字串检索*/
if(i>
0)
行号:
%d,次数:
%d,位置分别为:
l,i);
for(m=1;
m<
=i;
m++)
第%4d个字符"
wz[m]+1);
\n本软件自定义110个字节为一行\n\n"
}/*检索单词出现在文本文件中的行号、次数及其位置*/
voidsubstrio()
voidsubstrcount(),substrint();
chart;
while
(1)
===============================================\n"
||文本文件单词字串的定位统计及定位||\n"
||================================||\n"
||a.单词出现次数||\n"
||||\n"
||b.单词出现位置||\n"
====================================\n"
请输入:
\n"
&
t);
switch(t){
case'
a'
:
substrcount();
break;
b'
substrint();
default:
}
intmain()
voidcreat_text_file(),substrsum(),substrio();
intxz;
intt=1;
while(t){
system("
graftabl936"
/*在Win-TC中可以显示汉字*/
*************************************\n"
**文本文件的检索、字串的统计及定位**\n"
**1.建立文本文档**\n"
**2.文本单词汇总**\n"
**3.单词定位**\n"
**4.退出**\n"
printf("
请选择:
%d"
xz);
switch(xz){
case1:
creat_text_file();
case2:
substrsum();
case3:
substrio();
case4:
return0;
printf("
选择错误,重新选\n"
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 文本文件 单词 检索 计数