串的基本操作

Posted helenandyoyo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了串的基本操作相关的知识,希望对你有一定的参考价值。

#include<iostream>
using namespace std;
#define ok 1
#define error 0
typedef int Status;

//------------------串的堆分配存储表示-------------------
typedef struct
	char *ch;//若是非空串,则按串长分配存储区,否则ch为NULL
	int length;//串长度
HString;

//------------------基本操作的函数原型说明---------------
class StringOperation

public:
	//生成一个其值等于串常量chars的串T
	Status StrAssign(HString &T,char *chars,int length);
	//返回S的元素个数,称为串的长度
	int StrLength(HString S);
	//若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
	int StrCompare(HString S,HString T);
	//将S清为空串,并释放S所占空间
	Status ClearString(HString &S);
	//用T返回由S1和S2连接而成的新串
	Status Concat(HString &T,HString S1,HString S2);
	//1<=pos<=StrLength(S)且0<=len<=StrLength(S)-pos+1
	//返回串S的第pos个字符起长度为len 
	Status SubString(HString &Sub,HString S,int pos,int len);
	//若主串S中存在和串T值相同的子串,则返回它在主串中S中第pos个字符之后第一次出现的位置,否则函数值为0
	int Index(HString S,HString T,int pos);
	//采用KMP算法进行模式匹配
	int Index_KMP(HString S,HString T,int pos);
	//若串S,T,V存在,且串T是非空串,用V替换主串S中出现的所有与T相等的不重叠的子串
	Status Replace(HString &S,HString T,HString V);
	//若串S存在,则输出串S总的字符
	Status StrOutput(HString S);
	//若串S为空串则返回true,否则返回false
	Status StrEmpty(HString S);
	//在串S的第pos个字符之前插入串T
	Status StrInsert(HString &S,int pos,HString T);
	//串S存在,由串S复制得到串T
	Status StrCopy(HString &T,HString S);
	//从串S中删除第pos个字符起长度为len的子串
	Status StrDelete(HString &S,int pos,int len);
	//销毁串S
	Status StrDestroy(HString &S);
;//StringOperation

Status StringOperation::StrAssign(HString &T,char *chars,int length)

	int i=0;
	char *c=chars;
	if(T.ch)//T中存有字符串,则释放T原有空间
	
		delete T.ch;
		T.ch=NULL;
		T.length=0;
	//if
	if(0==length)//chars为空串
	
		T.ch=NULL;T.length=0;
	//if
	else
	
		T.ch=new char[length];
		if(!T.ch)
		
			cout<<"内存分配失败"<<endl;
			exit(-1);
		//if
		for(int k=0;k<length;k++)
			*(T.ch+k)=*(chars+k);
		T.length=length;
	//else
	return ok;
//StrAssign

int StringOperation::StrLength(HString S)

	return S.length;
//Strlength
 
int StringOperation::StrCompare(HString S,HString T)

	for(int i=0;i<S.length&&i<T.length;i++)
	
		if(S.ch[i]!=T.ch[i])
			return S.ch[i]-T.ch[i];
	//for
	return S.length-T.length;
//StrCompare

int StringOperation::ClearString(HString &S)

	if(S.ch)
	
		delete S.ch;
		S.ch=NULL;
	//if
	S.length=0;
	return ok;		
//ClearString
 
Status StringOperation::Concat(HString &T,HString S1,HString S2)

	if(T.ch)
	
		delete T.ch;
		T.ch=NULL;
	//if
	T.ch=new char[S1.length+S2.length];
	if(!T.ch)
	
		cout<<"内存分配不成功"<<endl;
		exit(-1);
	//if
	for(int i=0;i<S1.length;i++)
		T.ch[i]=S1.ch[i];
	for(int i=S1.length;i<S1.length+S2.length;i++)
		T.ch[i]=S2.ch[i-S1.length];
	T.length=S1.length+S2.length;
	return ok;
//Concat

Status StringOperation::SubString(HString &Sub,HString S,int pos,int len)

	if(pos<1||pos>S.length||len<0||len>S.length-pos+1)
		return error;
	if(Sub.ch)
	
		delete Sub.ch;
		Sub.ch=NULL;
	//if
	if(0==len)
	
		Sub.ch=NULL;Sub.length=0;
	//if
	else
	
		Sub.ch=new char[len];
		for(int i=0;i<len;i++)
			Sub.ch[i]=S.ch[pos-1+i];
		Sub.length=len;
	//else
	return ok;
//SubString

int StringOperation::Index(HString S,HString T,int pos)

	int i=pos,j=0,k=1;
	if(pos<1||pos>S.length)
		return error;
	while(i<S.length&&j<T.length)
	
		if(S.ch[i]==T.ch[j])
		
			i++;j++;
		//if
		else//从pos下一个位置重新匹配
		
			i=pos+k;k++;
			j=0;
		//else
	//while
	if(j>=T.length)//匹配成功
		return i-j+1;
	else
		return 0;
//Index

void get_next(HString T,int str[])

	int i=1,j=0;
	str[1]=0;
	while(i<T.length)
	
		if(0==j||T.ch[i]==T.ch[j])
		
			i++;j++;str[i]=j;
		//if
		else
			j=str[j];
	//while
//get_next
int StringOperation::Index_KMP(HString S,HString T,int pos)

	int next[20];
	get_next( T, next);
	if(pos<1||pos>S.length)
	
		cout<<"pos is error"<<endl;
		exit(-1);
	//if
	int i=pos, j=1;
	while(i<=S.length&&j<=T.length)
	
		if(0==j||S.ch[i-1]==T.ch[j-1])
		
			i++;j++;
		//if
		else j=next[j];
	//while
	if(j>=T.length)
		return i-T.length;
	else
		return 0;
//Index_KMP
Status StringOperation::Replace(HString &S,HString T,HString V)

	int i=1,locate=0;
	HString Sub,TT1,TT2;
	Sub.ch=NULL;Sub.length=0;
	TT1.ch=0;TT1.length=0;TT2.ch=0;TT2.length=0;
	while(i<=S.length-T.length+1)
	
		locate=Index(S,T,i);
		if(locate)
		
			if(T.length!=S.length-locate+1)//与T相等的串不在串S的末尾
				SubString(Sub,S,locate+T.length,S.length-(locate+T.length)+1);//将Pos后除T的剩余串复制到Sub中
			else
				ClearString(Sub);
			Concat(TT1,V,Sub);
			if(1<locate)//与T相等的串不在S的开头
				SubString(Sub,S,1,locate-1);//将串S中pos位置前的字符复制到Sub中
			else
				ClearString(Sub);
			Concat(TT2,Sub,TT1);
			StrAssign(S,TT2.ch,TT2.length);
			i=locate+V.length-1;
		//if
	//while
	StrDestroy(Sub);StrDestroy(TT1);StrDestroy(TT2);
	return ok;
//Replace

Status StringOperation::StrOutput(HString S)

	int i=0;
	while(i<S.length)
	
		cout<<S.ch[i];
		i++;
	//while
	return ok;
//HString

Status StringOperation::StrEmpty(HString S)

	if(S.length)
		return false;
	else
		return true;
//StrEmpty

Status StringOperation::StrInsert(HString &S,int pos,HString T)

	HString Sub,TT1,TT2;
	Sub.ch=NULL;TT1.ch=NULL;TT2.ch=NULL;
	Sub.length=0;TT1.length=0;TT2.length=0;
	if(pos>S.length||pos<1)
	
		cout<<"pos is error "<<endl;
		exit(-1);
	//if
	if(1==pos)
	
		Concat(TT1,T,S);
		StrAssign(S,TT1.ch,TT1.length);
	//if
	else
	
		SubString(Sub,S,pos,S.length-pos+1);
		Concat(TT1,T,Sub);
		SubString(Sub,S,1,pos-1);
		Concat(TT2,Sub,TT1);
		StrAssign(S,TT2.ch,TT2.length);
	//else
	StrDestroy(Sub);StrDestroy(TT1);StrDestroy(TT2);
	return ok;
//StrInsert

Status StringOperation::StrCopy(HString &T,HString S)

	StrAssign(T,S.ch,S.length);
	return ok;
//StrCopy

Status StringOperation::StrDelete(HString &S,int pos,int len)

	HString  Sub1,Sub2;
	Sub1.ch=NULL;Sub1.length=0;Sub2.ch=NULL;Sub2.length=0;
	if(pos<1||pos>S.length-len+1)
	
		cout<<"pos is error"<<endl;
		exit(-1);
	//if
	SubString(Sub1,S,pos+len,S.length-pos-len+1);
	SubString(Sub2,S,1,pos-1);
	Concat(S,Sub2,Sub1);
	StrDestroy(Sub1);StrDestroy(Sub2);
	return ok;
//StrDelete

Status StringOperation::StrDestroy(HString &S)

	if(S.ch)
	
		delete S.ch;S.ch=NULL;
	//if
	return ok;
//StrDestroy
void main()

	char str[12]="abcssasdsss",str1[4]="sss",str2[4]="vvv";
	StringOperation SOP;
	HString S,T,V;
	S.ch=NULL;T.ch=NULL,V.ch=NULL;
	SOP.StrAssign(S,str,11);
	SOP.StrAssign(T,str1,3);
	SOP.StrAssign(V,str2,3);
	cout<<"串S:";
	SOP.StrOutput(S);cout<<endl;
	cout<<"串T:";
	SOP.StrOutput(T);cout<<endl;
	cout<<"串V:";
	SOP.StrOutput(V);cout<<endl;
	cout<<"\\n"<<"采用KMP算法进行模式匹配:";
	cout<<SOP.Index_KMP(S,T,1)<<endl;
	cout<<"用串V替换S中与T相等的所有子串:";
	SOP.Replace(S,T,V);
	SOP.StrOutput(S);cout<<endl;
	cout<<"在串S的第10个字符之前插入串T:";
	SOP.StrInsert(S,10,T);
	SOP.StrOutput(S);cout<<endl;
	cout<<"删除串S从第2个字符起长度为3的子串:";
	SOP.StrDelete(S,2,3);
	SOP.StrOutput(S);cout<<endl;
//main

以上是关于串的基本操作的主要内容,如果未能解决你的问题,请参考以下文章

串和串的赋值操作

[BZOJ2555] SubString

CF1523C. Compression and Expansion(堆栈模拟)

CodeForce-797C Minimal string(贪心模拟)

ForeignGame [博弈论][DP]

POI2000病毒