字符串操作算法与数据结构课程设计最详细的操作含字符串加密和解密2.docx
《字符串操作算法与数据结构课程设计最详细的操作含字符串加密和解密2.docx》由会员分享,可在线阅读,更多相关《字符串操作算法与数据结构课程设计最详细的操作含字符串加密和解密2.docx(34页珍藏版)》请在冰豆网上搜索。
字符串操作算法与数据结构课程设计最详细的操作含字符串加密和解密2
基本全部操作都有,最重要是字符串的加密和解密!
1.算法思想
1、用结构体SString记录字符串信息,其中ch代表字符串,length代表字符串长度。
2、模式匹配:
1)穷举法的Index(S,T,pos):
从位置开始通过SubString截取S中T长度的字符串,并与T通过StrCompare进行比较,若找到则返回位置;否则继续。
若没找到,返回-1。
2)BF算法:
IndexBF(S,T,pos)
主串S从pos位置开始,模式串T从0位置开始,从目标串s=“s0s2…sn-1"的第一个字符开始和模式串t=“t0t2…tm-1"中的第一个字符比较,若相等,则继续逐个比较后续字符;否则从目标串s的第二个字符开始重新与模式串t的第一个字符进行比较。
依次类推,若从模式串s的i位置字符开始,每个字符依次和目标串t中的对应字符相等,则匹配成功,该算法返回i;否则,匹配失败,函数返回-1。
3)KMP算法:
该算法较BF算法有较大改进,主要是消除了主串指针的回溯,从而使算法效率有了某种程度的提高。
定义next[j]函数,表明当模式中第j个字符与主串中相应字符“失配”时,在模式中需重新和主串中该字符进行比较的字符的位置。
max{k|0next[j]=当此集合非空时
-1当j=0时
0其他情况
若“p0…pk-1”=“pj-k…pj-1”,即next[j]=k,则next[j+1]=?
①若pk=pj,则有“p0…pk-1pk”=“pj-k…pj-1pj”(0j+1发生不匹配,说明next[j+1]=k+1=next[j]+1。
②若pk≠pj,可把求next值问题看成是一个模式匹配问
题,整个模式串既是主串,又是子串。
Kmp:
从S的pos位置开始与T进行匹配,若S与T对应位置相等或T回到0位置时,S与T同时右移;否则T回到next[j]位置。
3、字符串的加密、解密:
1)Encrypt算法:
对字符串中的单个字符c的二进制形式进行操作,通过右移和与位运算等其分为两部分,存储在两个字符中。
2)Decrypt算法:
对字符串中的单个字符c的二进制形式进行操作,通过左移和与位运算等两个字符还原累加,得到原字符。
4.文本文件单词的检索与计数;
1)建立文件的实现思路是:
(1)定义一个串变量;
(2)定义文本文件;
(3)输入文件名,打开该文件;
(4)循环读入文本行,写入文本文件,其过程如下:
while(不是文件输入结束){
读入一文本行至串变量;
串变量写入文件;
输入是否结束输入标志;}
(5)关闭文件。
2)给定单词计数的实现思路是:
(1)输入要检索的文本文件名,打开相应的文件;
(2)输入要检索统计的单词;
(3)循环读文本文件,读入一行,将其送入定义好的串中,并求该串的实际长度,调用串匹配函数进行计数。
具体描述如下:
while(不是文件结束){
读入一行并到串中;
求出串长度;
模式匹配函数计数;}
(4)关闭文件,输出统计结果。
3)检索单词出现在文本文件中的行号、次数及其位置的实现思路是:
(1)输入要检索的文本文件名,打开相应的文件;
(2)输入要检索统计的单词;
(3)行计数器置初值0;
(4)while(不是文件结束){
读入一行到指定串中;
求出串长度;
行单词计数器0;
调用模式匹配函数匹配单词定位、该行匹配单词计数;
行号计数器加1;
if(行单词计数器!
=0)输出行号、该行有匹配单词的个数以及相应的位置;}
2、模块划分
1.串的模式匹配:
穷举法:
Index(S,T,pos)
S为主串,T为模式串,从pos位置开始进行
BF算法:
IndexBF(SStringS,SStringT,intpos)
朴素的模式匹配算法,S为主串,T为模式串,从pos位置开始进行。
KMP算法:
get_next(SStringT,intnext[])
获取字符串T对应的next[]数组。
IndexKMP(SStringS,SStringT,intpos,intnext[])
利用模式串T的next函数求T在主串S中第pos个字符之后的位置。
2.字符串的加密与解密:
加密:
Encrypt(SStringS,SString*T)
将字符串S加密后存储在T中
解密:
Decrypt(SStringS,SString*T)
将字符串S解密后存储到T中
3.文本文件单词的计数和检索:
CreatTextFile()
创建文本文件
SubStrCount()
利用模式匹配,给定单词计数
SubStrInd()
利用模式匹配,检索单词出现在文本文件中的行号、次数及其位置
intmatch(chara[],intn,charc)
判断字符是否为标点或空格,换行符等,若相符返回1,否则返回0。
3、数据结构
ADTString{
数据对象:
D={ai|ai∈CharacterSet,i=1,2,3,……n,n≥0}
数据关系:
R1={|a(i-1),ai∈D,i=2,……n}
基本操作:
InitString(&S,a[])
初始条件:
a[]是字符型数组。
操作结果:
生成一个其值为a[]的串S。
StrLength(S)
初始条件:
串S存在
操作结果:
返回的元素个数。
StrCompare(S,T)
初始条件:
串S、T存在。
操作结果:
若S>T,则返回值大于0;若SSubString(&sub,S,pos,len)
初始条件:
串S存在,0≤pos操作结果:
用sub返回串S的第pos下标起长度为len的字串。
StrInsert(&S,T,pos)
初始条件:
串S,T存在,0≤pos≤S.length。
操作结果:
在串S的第个下标开始插入串T。
StrDelete(&S,pos,len)
初始条件:
串S存在,0≤pos≤S.length-len。
操作结果:
从串的第pos个下标开始删除长度为len的子串。
StrContact(&S,T)
初始条件:
串S,T存在。
操作结果:
用S返回S与T连接而成的新串。
Index(S,T,pos)
初始条件:
串S、T存在,0≤pos≤S.length-1。
操作结果:
若主串S中存在与串T相同的串则返回从下标pos开始的第一个出现的位置,否则返回-1。
show(S)
初始条件:
串S存在。
操作结果:
显示串S。
}ADTString
4、源程序(格式调整,添加注释)
#include
#include
#defineMaxStrSize256
typedefstruct{
charch[MaxStrSize];
intlength;
}SString;//定义顺序串类型
//pos为下标
//实现串的赋值、比较、连接、插入和删除等操作,并在此基础上完成串的模式匹配
voidInitString(SString*s,chara[])
{inti,j;
for(j=0;a[j]!
='\0';j++);
for(i=0;is->ch[i]=a[i];
s->length=strlen(a);
}
//串赋值
intStrLength(SStrings)
{returns.length;}
//求串长
intStrCompare(SStrings,SStringt)
{inti;
for(i=0;iif(s.ch[i]!
=t.ch[i])returns.ch[i]-t.ch[i];
returns.length-t.length;}
//串比较
voidSubString(SString*sub,SStringS,intpos,intlen)
{inti;
for(i=0;isub->ch[i]=S.ch[pos+i];
sub->length=len;}
//截取串
voidStrInsert(SString*s,SStringt,intpos)
{inti,m,n;
m=s->length;
n=t.length;
for(i=m-1;i>=pos-1;i--)
s->ch[i+n]=s->ch[i];
for(i=0;is->ch[i+pos]=t.ch[i];
s->length=s->length+n;
}//插入算法
voidStrDelete(SString*s,intpos,intlen)
{inti;
for(i=pos+len;ilength;i++)
s->ch[i-len]=s->ch[i];
s->length=s->length-len;
}
//删除算法
voidStrContact(SString*s,SStringt)
{StrInsert(s,t,s->length);}
//连接算法
voidshow(SStringS)
{inti;
for(i=0;iprintf("%c",S.ch[i]);
}
//显示串
//-----------------加密与解密---------------------------
voidEncrypt(SStringS,SString*T)
{charc;
inti,h,l,j=0;
for(i=0;i{c=S.ch[i];
h=(c>>4)&0xf;//取前四位
l=c&0xf;//取后四位
T->ch[j]=h+'x';
T->ch[j+1]=l+'z';
j+=2;
}
T->length=2*S.length;
}
//加密
voidDecrypt(SStringS,SString*T)
{inti,h,l,m,n,j=0;
for(i=0;i{h=(S.ch[i]-'x');
l=(S.ch[i+1]-'z');
m=(h<<4);
n=(l&0xf);
T->ch[j]=m+n;
j++;}
T->length=S.length/2;
}
//解密
//------------模式匹配-----------------------
intIndex(SStringS,SStringT,intpos)
{inti,m,n;SStringsub;
if(pos>=0)
{n=StrLength(S);m=StrLength(T);i=pos;
while(i<=n-m)
{SubString(&sub,S,i,m);
if(StrCompare(sub,T)!
=0)
i++;
else
returni;
}
}
return-1;
}//穷举法
intIndexBF(SStringS,SStringT,intpos)
{inti,j,k=-1;
i=pos;j=0;
while(iif(S.ch[i]==T.ch[j]){i++;j++;}
else{i=i-j+1;j=0;}
}
if(j>=T.length)k=i-T.length;
returnk;
}
//BF算法
voidget_next(SStringT,intnext[])
{intj,k;
next[0]=-1;next[1]=0;
j=1;k=0;
while(jif(T.ch[j]==T.ch[k])
{k++;j++;next[j]=k;}
else
if(k==0)
{j++;
next[j]=0;
}
else
k=next[k];
}
}
intIndexKMP(SStringS,SStringT,intpos,intnext[])
{inti,j,k;
i=pos;j=0;k=-1;
while(iif(S.ch[i]==T.ch[j])
{i++;j++;}
else
if(j==0){i++;}
else
j=next[j];
}
if(j>=T.length)k=i-T.length;
returnk;
}
//KMP算法
//---------------文本文件单词的检索与计数------------------
intmatch(chara[],intn,charc)
{inti;
for(i=0;iif(a[i]==c)return1;
return0;
}
voidCreatTextFile()
{SStringS;
charfname[10],yn;
FILE*fp;
printf("输入要建立的文件名:
");
scanf("%s",fname);
fp=fopen(fname,"w");
yn='n';//输入结束标志初值
while(yn=='n'||yn=='N')
{printf("请输入一行文本:
");
gets(S.ch);gets(S.ch);
S.length=strlen(S.ch);
fwrite(&S,S.length,1,fp);
fprintf(fp,"%c",10);
printf("结束输入吗?
yorn:
");yn=getchar();}
fclose(fp);//关闭文件
printf("建立文件结束!
");
}
voidSubStrCount()
{chara[7]={',','.',';','!
','?
','','\n'};
FILE*fp;
SStringS,T;//定义两个串变量
charfname[10];
inti=0,j,k;
printf("输入文本文件名:
");
scanf("%s",fname);
fp=fopen(fname,"r");
printf("输入要统计计数的单词:
");
scanf("%s",T.ch);
T.length=strlen(T.ch);
while(!
feof(fp)){//扫描整个文本文件
memset(S.ch,'\0',256);
fgets(S.ch,256,fp);//读入一行文本
S.length=strlen(S.ch);
k=0;//初始化开始检索位置
while(k{j=IndexBF(S,T,k);//调用串匹配函数
if(j<0)break;
elseif(j==0)
{if(match(a,7,S.ch[T.length]))
i++;//单词计数器加1
k=j+T.length;//继续下一字串的检索
}
else{if(match(a,7,S.ch[j-1])&&match(a,7,S.ch[j+T.length]))
i++;//单词计数器加1
k=j+T.length;//继续下一字串的检索
}
}
}
printf("\n单词%s在文本文件%s中共出现%d次\n",T.ch,fname,i);
}//统计单词出现的个数
voidSubStrInd()
{chara[7]={',','.',';','!
','?
','','\n'};
FILE*fp;
SStringS,T;
charfname[10];
inti,j,k,l,m;
intwz[20];
printf("输入文本文件名:
");
scanf("%s",fname);
fp=fopen(fname,"r");
printf("输入要检索的单词:
");
scanf("%s",T.ch);
T.length=strlen(T.ch);
l=0;
while(!
feof(fp)){
memset(S.ch,'\0',256);
fgets(S.ch,256,fp);
S.length=strlen(S.ch);
l++;
k=0;
i=0;
while(k{j=IndexBF(S,T,k);
if(j<0)break;
elseif(j==0){
if(match(a,7,S.ch[T.length]))
{i++;
wz[i]=j;}
k=j+T.length;
}
else
{if(match(a,7,S.ch[j-1])&&match(a,7,S.ch[j+T.length]))
{i++;wz[i]=j;}
k=j+T.length;
}
}
if(i>0){
printf("行号:
%d,次数:
%d,位置分别为:
",l,i);
for(m=1;m<=i;m++)
printf("%4d",wz[m]+1);printf("\n");
}
}
}//检索单词出现在文本文件中的行号、次数及其位置
main()
{SStringS,T,M;
intxz,wz;
intnext[MaxStrSize];
chara[MaxStrSize],b[MaxStrSize];
do{printf("\n");
printf("*************************\n");
printf("*************************\n");
printf("*1.穷举法,KMP算法和BF算法*\n");
printf("*2.字符串的加密与解密*\n");
printf("*3.建立文本文件*\n");
printf("*4.单词字串的计数*\n");
printf("*5.单词字串的定位*\n");
printf("*0.退出整个程序*\n");
printf("请选择(0--5)");
scanf("%d",&xz);
switch(xz){
case1:
printf("\n请输入主串S:
");
gets(a);gets(a);
printf("\n请输入模式串T:
");
gets(b);
InitString(&S,a);
InitString(&T,b);
printf("\n主串S:
");show(S);
printf("\n模式串T:
");show(T);
printf("\n请输入开始匹配的下标:
");
scanf("%d",&wz);
printf("\n穷举法匹配位置:
%d",Index(S,T,wz)+1);
printf("\nBF算法匹配位置:
%d",IndexBF(S,T,wz)+1);
get_next(T,next);
printf("\nkmp算法匹配位置:
%d",IndexKMP(S,T,wz,next)+1);
break;
case2:
printf("\n请输入串S:
");
gets(a);gets(a);
InitString(&S,a);
printf("\n原字符串S:
");show(S);
Encrypt(S,&T);
printf("\n加密后串T:
");show(T);
Decrypt(T,&M);
printf("\n解密后串M:
");show(M);
break;
case3:
CreatTextFile();break;
case4:
SubStrCount();break;
case5:
SubStrInd();break;
case0:
return0;
default:
printf("选择错误,重新选\n");
}
}while
(1);
}
八、测试情况
程序的测试结果如下:
函数名:
stpcpy
功能:
拷贝一个字符串到另一个
用法:
char*stpcpy(char*destin,char*source);
程序例:
#include
#include
intmain(void)
{
charstring[10];
char*str1="abcdefghi";
stpcpy(string,str1);
printf("%s\n",string);
return0;
}
函数名:
strcat
功能:
字符串拼接函数
用法:
char*strcat(char*destin,char*source);
程序例:
#include
#include
intmain(void)
{
chardestination[25];
char*blank="",*c="C++",*Borland="Borland";
strcpy(destination,Borland);
strcat(destination,blank);
strcat(destination,c);
printf("%s\n",destination);
return0;
}
函数名:
strchr
功能:
在一个串中查找给定字符的第一个匹配之处\
用法:
char*strchr(char*str,charc);
程序例:
#include
#include
intmain(void)
{
charstring[15];
char*ptr,c='r';
strcpy(string,"Thisisastring");
ptr=strchr(string,c);
if(ptr)