navorse

  博客园 :: 首页 :: 新随笔 :: 联系 :: :: 管理 ::

串的操作

  串赋值StrAssign、串比较StrCompare、求串长StrLength、串连接Concat、求子串SubString五种操作构成串类型的最小操作子集。

  串的堆分配存储的实现:

struct HString
{
	char *chars;
	int len;
};

void StrInit(HString &S)
{
	S.chars=NULL;
	S.len=0;
}

Status StrAssign(HString &S,char *T)
{
	int i;
	int len=strlen(T);
	if(S.chars!=NULL)
		delete S.chars;
	S.chars=new char[len];
	if(S.chars==NULL)
		return WRONG;
	for(i=0;i<len;i++)
		S.chars[i]=T[i];
	S.len=len;
	return OK;
}

Status StrCopy(HString &S,HString T)
{
	int i;
	if(S.chars!=NULL)
		delete S.chars;
	S.chars=new char[T.len];
	if(S.chars==NULL)
		return WRONG;
	S.len=T.len;
	for(i=0;i<T.len;i++)
		S.chars[i]=T.chars[i];
	return OK;
}

bool StrEmpty(HString S)
{
	return S.chars==NULL&&S.len==0;
}

int StrCompare(HString H,HString T)
{
	//若S>T,值>0;若S=T,值=0;若S<T,值<0;
	int i=0;	
	while(i<H.len&&i<T.len)
		if(H.chars[i]!=T.chars[i])
			return H.chars[i]-T.chars[i];
		else
			i++;		
		return H.len-T.len;
}

int StrLen(HString S)
{
	return S.len;
}

void StrClear(HString &S)
{
	delete S.chars;
	S.chars=NULL;
	S.len=0;
}

Status StrConcat(HString &T,HString S1,HString S2)
{
	int i;
	if(T.chars!=NULL)
		delete T.chars;
	T.chars=new char[S1.len+S2.len];
	if(T.chars==NULL)
		return WRONG;
	T.len=S1.len+S2.len;
	for(i=0;i<S1.len;i++)
		T.chars[i]=S1.chars[i];
	for(i=0;i<S2.len;i++)
		T.chars[i+S1.len]=S2.chars[i];
	return OK;
}

Status StrSub(HString &Sub,HString S,int pos,int len)
{
	if(pos<1||pos>S.len||len<0||pos+len>S.len+1)
		return WRONG;
	int i;
	if(Sub.chars!=NULL)
		delete Sub.chars;	
	if(len==0)
	{
		Sub.chars=NULL;
		Sub.len=0;
	}
	else
	{
		Sub.chars=new char[len];
		if(Sub.chars==NULL)
			return WRONG;
		for(i=0;i<len;i++)
			Sub.chars[i]=S.chars[pos-1+i];
		Sub.len=len;
	}
	return OK;
}

void GetNext(HString T,int *next)
{
	int i=0,j=-1;
	next[0]=-1;
	while(i<T.len-1)
		if(j==-1||T.chars[i]==T.chars[j])
		{
			i++;
			j++;
			next[i]=j;
		}
		else
			j=next[j];
}

int Index(HString S,HString T,int pos)
{
	int *next,i=pos-1,j=0;
	next=new int[T.len];
	GetNext(T,next);
	while(i<S.len&&j<T.len)
		if(j==-1||S.chars[i]==T.chars[j])
		{
			i++;
			j++;
		}
		else
			j=next[j];
		if(j>=T.len)
			return i-T.len+1;
		else
			return 0;
	
}

Status StrInsert(HString &S,HString T,int pos)
{
	int i;
	char *newchars;
	if(pos<1||pos>S.len+1)
		return WRONG;
	newchars=new char[S.len+T.len];
	if(newchars==NULL)
		return WRONG;
	memcpy(newchars,S.chars,sizeof(char)*S.len);
	delete S.chars;
	//一定注意这个循环,想想为什么从后往前拷贝呢?因为从前会错的!
	for(i=S.len-1;i>=pos-1;i--)
	{
		newchars[i+T.len]=newchars[i];
	}
	for(i=0;i<T.len;i++)
	{
		newchars[i+pos-1]=T.chars[i];
	}
	S.chars=newchars;
	S.len+=T.len;
	return OK;
}

Status StrDelete(HString &S,int pos,int len)
{
	int i;
	char *newchars;
	if(pos+len>S.len+1)
		return WRONG;
	newchars=new char[S.len-len];
	memcpy(newchars,S.chars,S.len*sizeof(char));
	for(i=pos-1;i<=S.len-1;i++)
		newchars[i]=S.chars[i+len];
	delete S.chars;
	S.chars=newchars;
	S.len-=len;
	return OK;
}

Status Replace(HString &S,HString T,HString V)
{
	int i=1;
	if(S.chars==NULL)
		return WRONG;
	while(i)
	{
		i=Index(S,T,i);
		if(i!=0)
		{
			StrDelete(S,i,T.len);
			StrInsert(S,V,i);
			i+=V.len;
		} 
	}
	return OK;
}

void StrPrint(HString S)
{
	int i;
	for(i=0;i<S.len;i++)
		std::cout<<S.chars[i];
	std::cout<<std::endl;
}

posted on 2010-11-26 22:22  navorse  阅读(504)  评论(0)    收藏  举报