1. 串的定长顺序存储表示:类似于顺序表,用一组地址连续的存储单元存储串值,存储空间大小在最开始指定为固定值,如此在操作过程中如果出现串长超限的情况就统一用‘截尾法’处理。
#include <iostream>
using namespace std;
#define OK 1
#define ERROR -1
#define OVERFLOW -1
typedef int Status;
#define MAXSTRLEN 255 //串最大长度
struct SString
{
private:
char data[MAXSTRLEN];
public:
int Length;
SString(char *s)
{
int i=0;
while(s[i]!='\0')
{
data[i]=s[i];
i++;
}
Length=i;
}
char&operator[](int i)
{
if(i<0||i>Length-1)
{
cout<<"索引超限"<<endl;
}
return data[i];
}
Status Concat(SString s1)
{
//先判断连接后的长度是否超限
if(s1.Length+Length<=MAXSTRLEN)
{
for(int i=0; i<s1.Length; i++)
data[i+Length]=s1[i];
Length+=s1.Length;
}
else if(Length<MAXSTRLEN)
{
for(int i=0; i<MAXSTRLEN-Length; i++)
data[i+Length]=s1[i];
Length=MAXSTRLEN;
}
else
{
cout<<"当前串已满"<<endl;
}
return OK;
}
SString* SubString(int pos,int len)
{
//返回串从第pos个位置起len长度的子串
if(pos<1||pos>Length||len<0||len>Length-pos)
{
cout<<"索引错误/长度错误"<<endl;
}
char s[len];
for(int i=pos-1;i<pos+len-1;i++)
{
s[i-pos+1]=data[i];
}
return new SString(s);
}
int Index(SString s,int pos)
{
//模式匹配,如果从pos位置之后有一个子串和s相等则返回该子串位置索引,否则返回错误
int i=pos,j=0;
while(i<Length&&j<s.Length)
{
if(data[i]==s[j])
{
i++;j++;
}
else
{
i=i-j+1;
j=0;
}
}
if(j==s.Length)return i-s.Length;
else return ERROR;
}
void Print()
{
cout<<data<<endl;
}
};
int main()
{
SString *s=new SString("123"),
*t=new SString("456");
s->Concat(*t);
cout<<s->Length<<endl;
s->Print();
SString*m=(s->SubString(2,3));
m->Print();
cout<<s->Index(*m,1);
}
2. 串的堆分配存储表示:仍用一组地址连续的存储单元存放串值,但它们的存储空间是在程序执行过程中动态分配的。
#include <iostream>
#include <malloc.h>
using namespace std;
#define OK 1
#define ERROR -1
#define OVERFLOW -1
typedef int Status;
struct HString
{
private:
char*ch;
public:
int Length;
HString()
{
ch=NULL;
Length=0;
}
HString(char* s)
{
int i=0;
while(s[i++]!='\0');
Length=i-1;
ch=(char*)malloc(Length*sizeof(char));
i=0;
while(s[i]!='\0')
{
ch[i]=s[i];
i++;
}
}
char&operator[](int i)
{
if(i<0||i>Length-1)
{
cout<<"索引超限"<<endl;
}
return ch[i];
}
int StrCompare(HString s)
{
//若当前串>s,返回值>0,若等于s,返回值=0,若<s,返回值<0
for(int i=0;i<Length&&i<s.Length;i++)
{
if(ch[i]!=s[i])return ch[i]-s[i];
}
return Length-s.Length;
}
Status Clear()
{
//将self清空为空串
if(ch!=NULL)
{
free(ch);
ch=NULL;
}
Length=0;
}
void Concat(HString s)
{
ch=(char*)realloc(ch,(Length+s.Length)*sizeof(char));
for(int i=Length;i<(Length+s.Length);i++)
ch[i]=s[i-Length];
Length+=s.Length;
}
HString* SubString(int pos,int len)
{
//返回从串第pos个字符开始len长度的子串
if(pos<1||pos>Length||len<0||len>Length-pos)
{
cout<<"索引或长度错误"<<endl;
}
char*s=(char*)malloc(len*sizeof(char));
for(int i=pos-1;i<pos+len-1;i++)
s[i-pos+1]=ch[i];
return new HString(s);
}
void Print()
{
for(int i=0;i<Length;i++)
cout<<ch[i];
cout<<endl;
}
};
int main()
{
HString *s=new HString("123a"),
*t=new HString("123a");
cout<<s->StrCompare(*t)<<endl;
s->Concat(*t);
s->Print();
HString* m=s->SubString(2,3);
m->Print();
}
3. 串的块链存储表示:用链表方式存储,每个结点可以存储一个或多个字符,当存储多个字符时,存在最后一个结点不满的情况,可用“#”来表示空字符
#include <iostream>
using namespace std;
#define OK 1
#define ERROR -1
#define OVERFLOW -1
typedef int Status;
#define CHUNKSIZE 80 //块大小
struct Chunk{ //定义块结点
char ch[CHUNKSIZE];
Chunk*next;
};
struct LString
{
Chunk *head,*tail;//定义头指针和尾指针
int Length;//串的长度
};
4. 串的模式匹配算法:子串的定位操作通常称作串的模式匹配(以下在定长顺序存储结构串SString中使用)
int Index(SString s,int pos)
{
//模式匹配,如果从pos位置之后有一个子串和s相等则返回该子串位置索引,否则返回错误
int i=pos,j=0;
while(i<Length&&j<s.Length)
{
if(data[i]==s[j])
{
i++;j++;
}
else
{
i=i-j+1;
j=0;
}
}
if(j==s.Length)return i-s.Length;
else return ERROR;
}