数据结构实验 字符串类型的实现

数据结构实验 字符串类型的实现

实验内容
本人实现了字符串String类的基本操作,另外还完成了KMP算法以及查找子串的函数实现。类的定义中进行了构造函数重载以适应不同方式的初始化和赋值,此外进行了运算符“+=”重载以实现字符串的拼接,以及运算符“<<”重载以实现用cout输出String字符串。

代码

#include <iostream>
#include <cstdio>
using namespace std;

class String
{
	public:
		String();//默认构造函数 
		String(const char *c);//重载构造函数,char字符串类型 
		String(const String &str);//拷贝构造函数,String类型 
		String Substr(int pos,int n);//获取子串 
		void Clear();//清空字符串 
		bool Insert(String str,int pos);//插入字符 
		bool Delete(int pos,int n);//删除字符 
		int Find(String pat,int pos);//在字符串中从位置pos开始寻找子串pat并返回位置,若未找到返回-1 
		friend void getnext(String pat);//友元函数:KMP算法getnext函数 
		friend int kmp(String str,String pat);//友元函数:KMP算法核心函数 
		int Length();//获取串的长度 
		void Print();//打印字符串 
		String& operator +=(String str);//重载运算符“+=”,实现字符串的拼接 
		friend ostream & operator << (ostream &out,String &str);//重载运算符“<<”,实现用cout打印字符串 
	private:
		char *s;
		int length;
};//String类的实现 


String::String()
{
	s=new char[1];
	length=0;
}//默认构造函数 

String::String(const char *c)
{
	int len=0;
	while(c[len++]);
	len--;
	s=new char[len+1];
	for(int i=0;i<=len;i++)
		s[i]=c[i];
	length=len;
}//重载构造函数,char字符串类型 

String::String(const String &str)
{
	int len=str.length;
	s=new char[len+1];
	for(int i=0;i<=len;i++)
		s[i]=str.s[i];
	length=len;
}//拷贝构造函数,String类型 

String String::Substr(int pos,int n)
{
	char *p=new char[n+1];
	if(!p) return String();
	if(pos+n>length) return String();
	for(int i=0,j=pos;i<n;i++,j++)
		p[i]=s[j];
	String s(p);
	s.length=n;
	delete []p;
	return s;
}//获取子串 

void String::Clear()
{
	length=0;
}//清空字符串 

bool String::Insert(String str,int pos)
{
	if(pos<0||pos>length) return false;
	int len=str.Length();
	if(len==0) return true;
	char *p=new char[length+len+1];
	if(!p) return false;
	for(int i=0;i<length;i++)
		p[i]=s[i];
	for(int i=0;i<length+len-1-pos;i++)
		p[length+len-1-i]=p[length-1-i];
	for(int i=0;i<len;i++)
		p[pos+i]=str.s[i];
	s=p;
	length+=len;
	return true;
}//插入字符 

bool String::Delete(int pos,int n)
{
	if(pos<0||n<=0||pos+n>length) return false;
	for(int i=0;i<length-pos-n;i++)
		s[pos+i]=s[pos+n+i];
	length-=n;
	return true;
}//删除字符 

int String::Length()
{
	return length;
}//获取串的长度 

void String::Print()
{
	if(length==0)
	{
		cout<<"字符串为空串"<<endl;
		return;
	}
	for(int i=0;i<length;i++)
		cout<<s[i];
	cout<<endl;
}//打印字符串 


String& String::operator +=(String str)
{
	int newlen=length+str.Length();
	char *p=new char[newlen+1];
	if(!p) return *this;
	for(int i=0;i<length;i++)
		p[i]=s[i];
	for(int i=0;i<str.Length();i++)
		p[length+i]=str.s[i];
	s=p;
	length=newlen;
}//重载运算符“+=”,实现字符串的拼接 

ostream & operator << (ostream &out,String &str)
{
	if(str.Length()==0)
		cout<<"字符串为空串"<<endl;
	else
	{
		for(int i=0;i<str.Length();i++)
			cout<<str.s[i];
		cout<<endl;
	}
	return out;
}//重载运算符“<<”,实现用cout打印字符串 



int nxt[10005];//KMP算法next数组 
void getnext(String pat)
{
	int i=0,j=-1;
	int len=pat.Length();//先记录长度以节省时间 
	nxt[0]=-1;
	while(i<len)
	{
		if(j==-1||pat.s[i]==pat.s[j])
			nxt[++i]=++j;
		else
			j=nxt[j];
	}
	return;
}//KMP算法getnext函数 

int kmp(String str,String pat)
{
	int i=0,j=0,len1=str.Length(),len2=pat.Length();
	while(i<len1)
	{
		if(j==-1||str.s[i]==pat.s[j])
			i++,j++;
		else
			j=nxt[j];
		if(j==len2)
			return i-len2;//若找到,返回位置,注意是第一个字母的位置 
	}
	return -1;//未找到返回-1 
}//KMP算法核心函数 

int String::Find(String pat,int pos)
{
	getnext(pat);
	int temp=kmp(Substr(pos,length-pos),pat);
	if(temp>=0)
		return pos+temp;//若找到,返回子串在整个原串中的位置 
	else if(temp==-1)
		return -1;//未找到返回-1 
}//在字符串中从位置pos开始寻找子串str并返回位置,若未找到返回-1 



int main()
{
	//数据测试 
	char a[]="abcdefg";
	String s(a);//赋值 
	String ss=s;//赋值 
	s=ss.Substr(2,3);//获取子串 
	cout<<"字符串s长度为:"<<s.Length()<<endl;
	s.Print();
	s+=ss;//尾部拼接 
	cout<<"字符串s长度为:"<<s.Length()<<endl;
	s.Print();
	String t("xyz");//赋值 
	s.Insert(t,0);//插入字符 
	cout<<"字符串s长度为:"<<s.Length()<<endl;
	s.Print();
	s.Delete(3,3);//删除字符 
	cout<<"字符串s长度为:"<<s.Length()<<endl;
	s.Print();
	s+="aaa";//尾部拼接 
	cout<<"字符串s长度为:"<<s.Length()<<endl;
	s.Print();
	s.Delete(3,7);//删除字符 
	cout<<"字符串s长度为:"<<s.Length()<<endl;
	s.Print();
	s.Insert("bbb",3);//插入字符 
	cout<<"字符串s长度为:"<<s.Length()<<endl;
	cout<<s;//使用cout同样可以打印字符串 
	cout<<"找到子串位置:"<<s.Find("bbaa",0)<<endl;//从位置0查找子串 
	cout<<"找到子串位置:"<<s.Find("bbaa",5)<<endl;//从位置5查找子串 
	s.Clear();//清空字符串 
	cout<<"字符串s长度为:"<<s.Length()<<endl;
	cout<<s;
	return 0;
}

测试结果截图
在这里插入图片描述
问题解决和心得记录
这是我的第四次数据结构课程实验,完成了字符串String类及其基本操作的实现。我还进行了一些拓展练习,完成了KMP算法以及查找子串的函数实现。类的定义中进行了构造函数重载以适应不同方式的初始化和赋值,此外进行了运算符“+=”重载以实现字符串的拼接,以及运算符“<<”重载以实现用cout输出String字符串。
过程中曾出现过一些细节上的小失误,经过我的耐心修改和调试以后,最终都能够运行得到正确的结果。进行下标加减计算等处理还要更加细心一些,否则就可能造成错误。
经过近两个月的课程学习,我切实感受到写代码的能力是日积月累的,要感谢老师用心的指导,让我对数据结构这门课程有了更加深入的认识。课后我也会进行自主学习和习题练习,同时坚持每天在ACM俱乐部进行训练,编程能力相比过去有了明显的提升,真的非常有成就感。我将在后续的学习中再接再厉,争取在期末考试中取得理想的成绩。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

球王武磊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值