/*
串基于顺序存储结构的实现
串是一种特殊的线性表,但与线性表不同之处在于对串的操作往往是在子串上实现
结构体要求:数据域:char型
要实现的方法:
字符串的基本操作,大小比较及朴素模式匹配算法
*/
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 255 //最大空间
typedef struct{//串的顺序存储结构体
char ch[0+MAXSIZE];//0位置不用(为保证序号与下标一致)
int length; //串的当前长度
}SString;
//方法体
//创
bool InitSString(SString &S){//初始化串
S.length = 0;//将串长初始化为0;
return true;
}
void CreateSString(SString &S){//创建字符串
InitSString(S);
printf("\n请输入要创建的字符串,输入#结束\n");
char in;
scanf("%c",&in);
while(in!='#'&&S.length<MAXSIZE){
S.ch[++S.length] = in;
scanf("%c",&in);
}
getchar();//必须要有这步吸收换行符,否则创建第二个字符串T的时候会导致,T的首字符为换行符
}
//增,在第i个位置增加字符in
bool InsertSString(SString &S,int i,char in){
if(i<0||i>S.length+1){
printf("\n插入的位置有误!\n");
return false;
}else if(S.length==MAXSIZE){
printf("\n串已满!\n");
return false;
}
//输入的位置正确,开始进行插入操作
int j = ++S.length;//方便移动数组元素
while(j>i){//移动后让j自减
S.ch[j] = S.ch[j-1];
j--;
}
//循环结束后,i位置的空间就会空出来,此时直接插入目标值in
S.ch[i] = in;
return true;
}
//删,与增加字符类似,但移动的方向相反
bool DeleteSString(SString &S,int i){
if(S.length==0||i<0||i>S.length){
printf("\n字符串已空!\n");
return false;
}
//输入的位置正确,开始进行删除操作
while(i<S.length){//移动后让j自减
S.ch[i] = S.ch[i+1];
i++;
}
//循环结束后,该位置便被删除,长度应减1
S.length--;
return true;
}
//查
bool ShowSString(SString S){//查询所有字符串元素
if(S.length==0){//判断串是否为空串
printf("\n字符串为空!\n");
return false;
}
//串非空,开始输出字符串内容
int i = 1;
printf("\n字符串为:\n");
while(i<=S.length){
printf("%c",S.ch[i++]);
}
}
//找子串,为模式匹配做准备
bool SubString(SString &Sub,SString S,int sta,int len){//从sta位置开始,找长度为len的字符串
if(sta+len-1 > S.length){
printf("\n\n子串大小超过主串!\n");
return false;
}
//可找到子串,开始赋值子串给Sub
for(int i=sta; i < sta+len;i++){
Sub.ch[i-sta+1] = S.ch[i];//赋值给子串
}
//赋值成功
Sub.length = len;
return true;
}
//比较两子串的大小关系(返回值大于0则前者大于后者,等于则相等)
int StrCompare(SString S,SString T){
for(int i=1; i<=S.length&&i<=T.length; i++){
if(S.ch[i]!=T.ch[i])//找到第一个字符不相等的位置,则直接返回它两的ASCII码差值
return (S.ch[i] - T.ch[i]);//如果大于0则说明前者大于后者
}
//始终没找到不相等的字符,直接返回两者的字符长度差值
return S.length - T.length;//直接返回两者的大小长度
}
//模式匹配算法,需要使用大小匹配和找子串功能
int Index(SString S,SString ser){//找到ser串在主串S中是否出现过,并返回首次出现的位置
int i =1;//ser串可能出现的首位置
int n = S.length,m = ser.length;
SString Sub;//模式匹配的子串
while(i+m <= n+1){//当首位置加查找的子串长 > 主串长度加1时应结束循环
SubString(Sub,S,i,m);//从i开始从主串中依次找到对应的子串
if(StrCompare(Sub,ser)!=0) i++;//看模式串跟目标串是否相等,不等则i自增,相等则返回首位置i
else{
printf("目标首元素在第%d个位置",i);
return i;
}
}
//若没找到,则返回0
printf("未找到目标!\n");
return 0;
}
int main(){
SString S;
CreateSString(S);
ShowSString(S);
// printf("\n\n插入元素测试");
// InsertSString(S,3,'M');
// ShowSString(S);
//
// printf("\n\n删除元素测试");
// DeleteSString(S,3);
// ShowSString(S);
//
// 子串功能测试
// printf("\n\n找子串测试");
// SString Sub;
// SubString(Sub,S,2,3);
// ShowSString(Sub);
// 大小比较测试 , 这里时不时开始出现乱码,而且只能输出S>T
printf("\n大小比较测试");
SString T;
printf("\n请输入要比较的新字符串:");
CreateSString(T);
int result = StrCompare(S,T);
if(result>0){
printf("S>T\n");
}else if(result==0){
printf("s=t\n");
}else{
printf("S<T\n");
}
// 模式匹配算法测试
printf("\n模式匹配算法测试\n");
SString ser;
CreateSString(ser);
Index(S,ser);
}