关于用建立string类来求两个字符串的最长公共子串问题理解

题目要求:输入两个字符串,输出它们的最长公共子串,包括长度。

设计一个类String,包括一个len(字符串长度)和字符串指针s。

这是一个简单思路:

 讲解一下:

对于两个输入的字符串,在其成员函数知道其长度后,便可以开始查找出相同字符串:

定义:

可以定义一个  int类型的k,目的是当遍历到两字符串中相同字符时继续往下遍历时可以用k来使两字符同时往后读取,再往后读取只需将k进行  ++处理即可;

然后还需定义length记录最大相同字串的长度,index记录其索引位置;

再定义一个length1来记录当前相同字符串的长度,若>length 就取代。

思路分析:

int index=-1,length=0,length1=0,i=0,j,k;
		while (i<str1.len)             //插入循环进行遍历处理
		{    j=0;                     //每次下面数组遍历玩之后第一个字符串数组重新开始遍历
			while(j<str2.len)        //在不超过其长度的条件下遍历,超过就没有丝毫意义了
			{
		    	if (str1.s[i]==str2.s[j])    //当两者字符相同时进入判定
				{  length1=1;                //相同长度即可以初始化为1
				    k=1;
				  while (k<Max)               //在k不超过其最大长度的情况下遍历
				  {  if ((str1.s[i+k]==str2.s[j+k])&&(str1.s[i+k]!='\0'))
                        //在两字符串数组同时往后遍历k个单元依旧相同,且未到字符串结尾处'\0'
				  {    length1++;     //相同字符串的长度加一
				         k++;}	        //继续往后遍历
				     else break;       
         //不满足str1.s[i+k]==str2.s[j+k])&&(str1.s[i+k]!='\0')条件就跳出循环
				  }
	        	  if (length1>length)
          //比较相同字符串长度,存储最大字符串的长度和索引
				  {  
		         	index=i;
		           length=length1;
				  }
		        j+=length1;
            //跳过已确定的相同字符串
				}
		       else j++;
			}
	        	i++;
		}

思路在文中进行了标注;

这个函数也是其中最重要的函数;

下面是完整代码及简单讲解:

 类的声明:

 #include <iostream>    
  #include <cstring>
  using namespace std;//头文件声明
    const int Max=1000;//设置最大长度
    class Stringa
  {  
    public:
     Stringa( )                             //不带形参的构造函数,目的为初始化
	 {len=0;
      s=new char[Max];
	  	 }

	 Stringa(Stringa &m )                  //复制构造函数,用于复制String这个类的对象
	 {len=m.len;
  	 s=new char[Max];                        //深复制,不仅仅只是地址复制
	 strcpy(s, m.s);
		 }       

	 Stringa operator=(const Stringa &m)          //赋值重载函数,用一个对象给另一个对象赋值
{    len=m.len;
  	 s=new char[Max];
	 strcpy(s,m.s);
	  return (*this);
	 }  

    void getstring( )                        //用于读入字符串的成员函数
	{  cout<<"输入字符串:  " ;
	   cin.getline(s, Max);                   
	   len=strlen(s);
	   }
	void display( )
	{ cout<<"字符串="<<s<<"(长度为"<<len<<")"<<endl;  }    //输出字符串并写出长度

	friend Stringa maxsubstring(Stringa str1, Stringa str2);  
        //友元函数找最大公共子串的声明

	~Stringa( )                            //析构函数删除空间
	 {  delete [ ]s;}
	
    private:                                //数据成员len代表长度,*s存储字符串
	  int len;
      char *s;
	};

找最大公共子串的函数:

 Stringa maxsubstring(Stringa str1,Stringa str2)
  {int index=-1,length=0,length1=0,i=0,j,k;
		while (i<str1.len)             //插入循环进行遍历处理
		{    j=0;                     //每次下面数组遍历玩之后第一个字符串数组重新开始遍历
			while(j<str2.len)        //在不超过其长度的条件下遍历,超过就没有丝毫意义了
			{
		    	if (str1.s[i]==str2.s[j])    //当两者字符相同时进入判定
				{  length1=1;                //相同长度即可以初始化为1
				    k=1;
				  while (k<Max)               //在k不超过其最大长度的情况下遍历
				  {  if ((str1.s[i+k]==str2.s[j+k])&&(str1.s[i+k]!='\0'))
                        //在两字符串数组同时往后遍历k个单元依旧相同,且未到字符串结尾处'\0'
				  {    length1++;     //相同字符串的长度加一
				         k++;}	        //继续往后遍历
				     else break;       
         //不满足str1.s[i+k]==str2.s[j+k])&&(str1.s[i+k]!='\0')条件就跳出循环
				  }
	        	  if (length1>length)
          //比较相同字符串长度,存储最大字符串的长度和索引
				  {  
		         	index=i;
		           length=length1;
				  }
		        j+=length1;
            //跳过已确定的相同字符串
				}
		       else j++;
			}
	        	i++;
		}

     Stringa temp;
	 if ((index!=-1)&&(length>0))
	 {	if (str1.s[index]==' ')	              
	 {    if (length==1)                   //当找到的公共子串中是空格时,也等同于没有找到公                    共子串	             
	       { temp.len=0;
		 temp.s[0]='\0'; 
	    return temp;
	 }
	    else                               //  当找到的公共子串的第一个字符是空格时,将第一个空格去掉后再将剩下的字符作为公共子串输出
		{index+=1;
		length-=1;  }   
	 }
		if (str1.s[index+length-1]==' ')    //  当找到的公共子串的最后一个字符是空格时,将最后一个空格去掉后再将剩下的字符作为公共子串输出
			 {  length-=1;}   
	 	for (int t=0;t<length;t++)
	     temp.s[t]=str1.s[index+t];
    	 temp.len=length;	 
	   temp.s[length]='\0';	  	 
	   	 	 }
     else                                  //没有找到公共子串	 
		 { temp.len=length;
	 temp.s[0]='\0';}
	 return temp;	
     }

主函数:

int main( )
	   {Stringa s1,s2,s3;
	   s1.getstring( );
	   s2.getstring( );
       
	   cout<<"  s1";
	   s1.display( );
	   cout<<"  s2";
	   s2.display( );
 	   cout<<"  s1和s2最长公共子";
	   s3=maxsubstring(s1,s2);
       s3.display( );	   
	   return 0;	   
	   }

 运行结果:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zsl_xgbandage

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

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

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

打赏作者

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

抵扣说明:

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

余额充值