串
串的简单模式匹配
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct
{
char data[MAXSIZE];//存放顺序串串值
int len;//顺序串长度
}SeqString;//顺序串类型
int StrIndex_BF(SeqString*s,SeqString *T)
{//简单匹配模式
int i=0,j=0;//i\j分别指向S或串T的指针
while(i<s->len&&j<T->len)//当未到串S或串T的串尾时
{
if(s->data[i]==T->data[j])//两串当前位置上的字符配对时
{
i++;
j++;//将i\j指针顺序下移一个位置继续进行匹配
}
else//两串当前位置上的字符不匹配时
{
i=i-j+1;//将指针i调至主串S新一趟开始的匹配位置
j=0;//将指针J调至子串T的第一个字符位置
}
}
if(j>=T->len)//已匹配完子串的最后一个字符
return(i-T->len);//返回子串在主串S中的位置
else
return (-1);//主串S中没有与子串T相同的子串
}
void gets1(SeqString *p)//给p->data数组输入一个字符串
{
int i=0;
char ch;
p->len=0;//初始串长度为0
scanf("%c",&ch);//给p->data数组输入一个字符串
while(ch!='\n')
{
p->data[i++]=ch;
p->len++;
scanf("%c",&ch);
}
p->data[i++]='\0';//置串结束标志
}
void main()
{
int i;
SeqString *s,*t;//定义串变量
s=(SeqString *)malloc(sizeof(SeqString));//生成主串的存储空间
t=(SeqString *)malloc(sizeof(SeqString));//生成子串的存储空间
printf("Input main string S:\n");
gets1(s);//输入一个字符串作为主串
printf("Output main stringS:\n");
puts(s->data);//输出主串
printf("Input substring T:\n");
gets1(t);//输入子串
printf("Output substring T:\n");
puts(t->data);//输出子串
i=StrIndex_BF(s,t);//对主串和子串进行模式匹配
if(i==-1)
printf("No match string!\n");//主串中没有于子串匹配的子串
else
printf("Match position%d\n",i+1);//匹配成功,输出子串在主串中的起始位置
}
串的无回溯KMP匹配
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct
{
char data[MAXSIZE];//存放顺序串串值
int len;//顺序串长度
}SeqString;//类型
void GetNext(SeqString *T,intnext [])//有子串T求next值
{
int j=0,k=-1;
next[0]=-1;
while(j<T->len-1)
{
if(k==-1||T->data[j]==T->data[k])//k为-1或子串T中的j等于tk时
{
j++;
k++;//现在j\k值均加一
next[j]=k;
}
else
k=next[k];//找下一个k
}
}
int KMPIndex(SeqString*S,SeqString *T)//KMN算法
{
int next[MAXSIZE],i=0,j=0;
GetNext(T,next);//求next数组
while(i<S->len&&j<T->data[j])
if(j==-1||S->data[i]==T->data[j])//满足j==-1或si==tj都使i和j加一
{
i++;
j++;
}
else
j=next[j];//i不变,j回退至j=next【j】
if(j==T->len)
return i-T->len;//匹配成功返回下标
else
return -1;//匹配失败
}
void gets1(SeqString *p)//给p-》数组输入一个字符串
{
int i=0;
char ch;
p->len=0;//初始串长度为0
scanf("%c",&ch);//给数组输入一个字符串
while(ch!='\n')
{
p->data[i++]=ch;
p->len++;
scanf("%c",&ch);
}
p->data[i++]='\0';//置空标志
}
void main()
{
int i;
SeqString *s,*t;//定义变量
s=(SeqString *)malloc(sizeof(SeqString));
t=(SeqString *)malloc(sizeof(SeqString));
printf("Input main string S:\n");
gets1(s);
printf("Output main stringS:\n");
puts(s->data);
printf("Input substring T:\n");
gets1(t);
printf("Output substring T:\n");
puts(t->data);
i=KMPIndex(s,t);
if(i==-1)
printf("No match string !\n");
else
printf("Match position:%d\n",i+1);
}
链串中串的插入
#include <stdio.h>
#include <stdlib.h>
typedef struct snode
{
char data;
struct snode *next;
}LiString;//链串结点类型
void StrAssingn(LiString**s,char str[])//尾插法建立链串
{
LiString *p,*r;
int i;
*s=(LiString *)malloc(sizeof(LiString));//建立连串头结点
r=*s;//r始终指向链串s的尾结点
for(i=0;str[i]!='\0';i++)//将数组str中的字符逐个转化为链串s中的结点
{
p=(LiString *)malloc(sizeof(LiString));
p->data=str[i];
r->next=p;
r=p;
}
r->next=NULL;//将最终生成的链串尾结点的空指针域置空
}
void StrInsert(LiString*s,int i,LiString *t)//将链串t插入到链串第i个节点位置
{
LiString *p,*r;
int k;
p=s->next;//p指向链串的第一个数据结点
for(k=0;k<i-1;k++)//在链串中查找指向第i个结点的指针值
p=p->next;
r=p->next;//将链串s中由第i个结点开始的串暂存于r
p->next=t->next;//将链串t由第一个数据结点开始连接到链串s的第i-1个结点之后
p=t;//p指向链串t的头结点
while(p->next!=NULL)//查找链串t的尾结点
p=p->next;
p->next=r;
}
void main()
{
LiString *head1,*head2,*p;
charc1[20]="ABCD",c2[10]="abcd";
StrAssingn(&head1,c1);//建立链串head1
StrAssingn(&head2,c2);//建立链串head2
StrInsert(head1,2,head2);//将链串head2插入到链串head1中
p=head1->next;//输出插入后的链串
while(p!=NULL)
{
printf("%2c",p->data);
p=p->next;
}
printf("\n");
}
链串中求子串
#include <stdio.h>
#include <stdlib.h>
typedef struct snode
{
char data;
struct snode *next;
}LiString;
void StrAssingn(LiString**s,char str[])
{
LiString *p,*r;
int i;
*s=(LiString *)malloc(sizeof(LiString));//建立串头结点
r=*s;//r始终指向串的尾结点
for(i=0;str[i]!='\0';i++)//将数组中的字符逐个转化为链串中的结点
{
p=(LiString *)malloc(sizeof(LiString));
p->data=str[i];
r->next=p;
r=p;
}
r->next=NULL;//将最终生成的链串尾结点的指针置空
}
int StrLength(LiString *s)
{
int i=0;
LiString *p=s->next;//使p指向链串的第一个数据结点
while(p!=NULL)
{
i++;
p=p->next;
}
return i;//返回串长度
}
void SubStr(LiString*s,LiString **str,int i,int len)
{//对链串求子串并存放于链串str中
LiString *p,*q,*r;
int k;
p=s->next;//p指向链串的第一个数据结点
*str=(LiString*)malloc(sizeof(LiString));//生成链串的头结点
(*str)->next=NULL;
r=*str;//r指向链串的尾结点
if(i<1||i>StrLength(s)||len<0||i+len-1>StrLength(s))
goto L1;//参数错误,生成空链串
for(k=0;k<i-1;k++)
p=p->next;//p定位于链串的第i个结点
for(k=0;k<len;k++)//将链串有第i个结点开始的len个结点复制到链串str中
{
q=(LiString*)malloc(sizeof(LiString));//生成一个有q指向的结点
q->data=p->data;//复制链串s当前指针p所指的结点数据给*q
r->next=q;
r=q;
p=p->next;//链串s的指针顺序指向下一个结点,以便链串str中的指针q继续复制
}
r->next=NULL;//将链尾str中尾结点的指针域置空
L1: ;
}
void main()
{
LiString *head1,*head2,*p;
char c1[20]="ABCabD";
StrAssingn(&head1,c1);//建立链串head1
SubStr(head1,&head2,3,3);//对链串head1求子串并存放于链串head2中
p=head2->next;//输出新生成的链串head2
while(p!=NULL)
{
printf("%2c",p->data);
p=p->next;
}
printf("\n");
}
生成串链与求串长、串链接计算
#include <stdio.h>
#include <stdlib.h>
typedef struct snode
{
char data;
struct snode *next;
}LiString;//链串结点类型
void StrAssingn(LiString**s,char str[])//尾插法建立链串
{
LiString *p,*r;
int i;
*s=(LiString *)malloc(sizeof(LiString));//建立链串头结点
r=*s;//r始终指向链串尾结点
for(i=0;str[i]!='\0';i++)//将数组中的字符逐个转化为链串s中的结点
{
p=(LiString *)malloc(sizeof(LiString));
p->data=str[i];
r->next=p;
r=p;
}
r->next=NULL;//将生成的链串s尾结点的指针域置空
}
int StrLength(LiString *s)//求串长
{
int i=0;
LiString *p=s->next;//使p指向串s的第一个数据结点
while(p!=NULL)
{
i++;
p=p->next;
}
return i;//返回串长的长度值
}
void StrCat(LiString*s,LiString *t)//将链串s和串t链接成新的链串s
{
LiString *p,*q,*r,*str;
str=(LiString *)malloc(sizeof(LiString));
r=str;//r指向链串str的尾结点
p=t->next;//p指向链串t的第一个数据结点
while(p!=NULL)//将链串t复制到链串*str
{
q=(LiString *)malloc(sizeof(LiString));
q->data=p->data;
r->next=q;
r=q;
p=p->next;
}
r->next=NULL;//链串str中尾结点的指针域置空
p=s;
while(p->next!=NULL)//寻找s的尾结点
p=p->next;
p->next=str->next;//将链串str链到链串s的尾结点之后
free(str);//回收链串str的头结点
}
void main()
{
LiString *head1,*head2,*p;
char c1[20]="ABCD",c2[10]="abcd";
StrAssingn(&head1,c1);//建立链串head1
StrAssingn(&head2,c2);//建立链串head2
printf("head1=%d\n",StrLength(head1));//输出链串head1的长度
StrCat(head1,head2);//将链串head1和链串head2连接成新的链串head1
p=head1->next;//输出连接后的链串head1
while(p!=NULL)
{
printf("%2c",p->data);
p=p->next;
}
printf("\n");
}
生成串链与求串长、串链接计算1
#include <stdio.h>
#include <stdlib.h>
typedef struct snode
{
char data;
struct snode *next;
}LiString;//链串结点类型
void StrAssingn(LiString**s,char str[])//尾插法建立链串
{
LiString *p,*r;
int i;
*s=(LiString *)malloc(sizeof(LiString));//建立链串头结点
r=*s;//r始终指向链串尾结点
for(i=0;str[i]!='\0';i++)//将数组中的字符逐个转化为链串s中的结点
{
p=(LiString *)malloc(sizeof(LiString));
p->data=str[i];
r->next=p;
r=p;
}
r->next=NULL;//将生成的链串s尾结点的指针域置空
}
int StrLength(LiString *s)//求串长
{
int i=0;
LiString *p=s->next;//使p指向串s的第一个数据结点
while(p!=NULL)
{
i++;
p=p->next;
}
return i;//返回串长的长度值
}
void StrCat(LiString*s,LiString *t)//将链串s和串t链接成新的链串s
{
LiString *p,*q;
p=s;
q=t;
while(p->next!=NULL)
p=p->next;
p->next=q->next;
}
void main()
{
LiString *head1,*head2,*p;
char c1[20]="ABCD",c2[10]="abcd";
StrAssingn(&head1,c1);//建立链串head1
StrAssingn(&head2,c2);//建立链串head2
printf("head1=%d\n",StrLength(head1));//输出链串head1的长度
StrCat(head1,head2);//将链串head1和链串head2连接成新的链串head1
p=head1->next;//输出连接后的链串head1
while(p!=NULL)
{
printf("%2c",p->data);
p=p->next;
}
printf("\n");
}
顺序串基本实现
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 50
int StrLength(char *s)//求串长
{
int i=0;
while(s[i]!='\0')//对串中的字符个数进行计数直到遇见“\0"为止
i++;
return i;//返回串长值
}
int StrCat(char s1[],chars2[])//串链接
{
int i,j,len1,len2;
len1=StrLength(s1);//len1为串s1的长度
len2=StrLength(s2);//len2为串s2的长度
if(len1+len2>MAXSIZE-1)
return 0;//串s1的存储空间不够,返回错误代码
i=0;
j=0;
while(s1[i]!='\0')//找到串s1的串尾
i++;
while(s2[j]!='\0')//将串s2的串值复制到串s1的串尾
s1[i++]=s2[j++];
s1[i]='\0';//置串结束标志
return 1;//串链接成功
}
int SubStr(char *s,chart[],int i,int len)//求子串
{
int j,slen;
slen=StrLength(s);
if(i<1||i>slen||len<0||len>slen-i+1)//给定参数有错,返回错误代码
return 0;
for(j=0;j<len;j++)//复制串s中的指定子串到串t
t[j]=s[i+j-1];
t[i]='\0';//给子串t置结束标志
return 1;//求子串成功返回1
}
int StrCmp(char *s1,char*s2)//串比较
{
int i=0;
while(s1[i]==s2[i]&&s1[i]!='\0')//两串对应位置上的字符进行比较
i++;
return(s1[i]-s2[i]);
}
int StrInsert(char *s,inti,char *t)//串插入
{
char str[MAXSIZE];
int j,k,len1,len2;
len1=StrLength(s);
len2=StrLength(t);
if(i<0||i>len1+1||len1+len2>MAXSIZE-1)
return 0;//参数不正确或主串数组空间插不了子串t返回错误代码
k=i;
for(j=0;s[k]!='\0';j++)//将子串中由位置i开始一直到s串尾的子串赋给串str
str[j]=s[k++];
str[j]='\0';
j=0;
while(t[j]!='\0')//将子串t插入到主串s的i位置处
s[i++]=t[j++];
j=0;
while(str[j]!='\0')//再将暂存于串str的子串连接到刚复制到串s的子串t后面
s[i++]=str[j++];
s[i]='\0';//置串s结束标志
return 1;//串插入成功
}
void main()
{
charx1[50]="abcdefghijk",x2[30]="mnopqrstuvwxyz",x3[20];
puts(x1);//输出串
printf("Length of string x1 is %d\n",StrLength(x1));//输出串长度
if(StrCat(x1,x2))//将x2链接于串x1之后
{
printf("Output x1 afterchain:\n");
puts(x1);//输出连接后的串x1
}
else
printf("Chain x1 and x2fail!\n");//连接失败
if(SubStr(x1,x3,5,12))//对x1求子串并存放到串x3中
{
printf("String :\n");
puts(x3);//输出存放x3中的子串
}
else
printf("Error!\n");//求子串出错
if(StrCmp(x1,x2)>0)//串比较
printf("x1 is lager!\n");
else
printf("x2 is lager!\n");
if(StrInsert(x2,5,"aaaaa"))//将串aaaaa插入到串x2中
{
printf("Output x2 after insert:\n");
puts(x2);//输出插入后的串x2
}
else
printf("Insert fail!\n");//插入失败
}