(重要题目)POJ 1226 Substrings(…

来源:互联网 发布:南京plc编程培训机构 编辑:程序博客网 时间:2024/06/05 18:57

吐槽:(直接忽视)首先,写下第一次敲这个代码的感悟:好吧,找错找了3天的一题,然后错误找到,数组开小了,然后找呀找呀,找呀找,然后怀疑自己的思路,虽然稍微麻烦点,可能超时神马的,但是不应该WA呀,于是自己深刻反省反省,自己的思路到底有何问题,最后发现没问题,错在哪?错在蛋痛的数组开小了上。哥不就是数组开小了,你应该给我报个RE呀,你报个RE给我,我再错,我也就不说啥了,但是你妹的一直给我报WA是何居心,然后我就一直没往数组开小了这方面想。好吧,还是自己不够细心,一开始数组开小了。。。

 

 

正题:先写一下自己最初不是很成熟的算法,速度很慢,但是很容易想到。看到有人用KMP模板,或者一些挺牛的算法直接水掉,自己那是一个蛋痛,写完这段代码后继续在写稍微升级点的版本。不断优化,然后学习一些KMP,毕竟现在还是新手阶段,慢慢来吧、(重要题目)POJ <wbr>1226 <wbr>Substrings(子串处理,必须熟练掌握)

 

题意:给了n个测试的字符串,然后要求求出这n个字符串最长的共同的子串的长度,(注意:正序和逆序如果有这个子串都成立,就是正序逆序的都要检查),输出最长的长度就好。

 

分析:思路就是,先将正序和逆序的数组都求出来,求逆序的时候用了一个sttrev,查了下函数手册,是用在字符数组中的,在cstring中,然后我是用string写的,所以就自己重载了一遍,用了个反向迭代器,就是rbegin和rend。存完了正序逆序的数组后,在求完子串之前都用正序的字符串就行了。然后,先筛选出最短的字符串,

再用一个数组存储下所有的子串,用了substr函数,(这样的存储比较耗时,也就导致了最后的运行时间比较长,需要数组范围比较大,其实完全可以从最长的子串开始筛选,会省很多时间,如果成立,就能直接结束循环,第二次写的时候就按这种思路改),然后用了一个find函数去筛选(不过看别人大多数都是用的strstr,暂时还不知道怎么用,去研究研究去),最后筛选的所有的子串的结果的长度重新存一个length[10000]数组中,用下sort函数去排序,输出最大的就行了。

 

第一次写的整体的思路很简单,虽然实现稍微复杂点,但是不用考虑太多东西。第二次写的时候要改进一下

 

贴一下AC代码吧,速度比较慢:(764k,110ms)

 

C++语言:
#include<iostream>
#include<string>
#include<algorithm>
usingnamespacestd;
string sttrev(string a)   //将字符串逆序
{
   string str(a.rbegin(),a.rend());
   return str;
}

intmain()
{
   string a[105][2];
   int length[105];
   int original_length[105];
   int temp_length[105];
   string sub_string[10000];
   int i ,j ;
   int num;   //用于记录是第几个数据
   int t ,n;

   cin>>t;
   while (t--)
   {
      int temp,number[10000]={0};
      int temp_number[2]={0};
      cin>>n;
      for(i =0;i < n;i ++  //直接存储正序和逆序的字符串
      {
         cin>>a[i][0];
         a[i][1]=sttrev(a[i][0]);
         length[i]= a[i][0].length();
         original_length[i]=length[i];
      }
      sort(length,length+n);
      for(i =0;i < n ;i ++)
      {
         if(original_length[i]== length[0])      //选择出最短的一段字符串,节省后面的筛选时间
         {
             num =i;
             break;
         }
      }
      temp=0;
      for(i =0;i<length[0];i++)
      {
         for(j= length[0]-i;j>=1 ; j --)
         {
             sub_string[temp]= a[num][0].substr(i,j);
             temp++;
         }
      }
   

      for(i =0;i< temp ; i ++)
      {
         for(j= 0; j < n; j ++)
         {
             temp_number[0] =a[j][0].find(sub_string[i]);
             //cout<<"text0:"<<temp_number[0]<<endl;
             temp_number[1] =a[j][1].find(sub_string[i]);
             //cout<<"text1:"<<temp_number[1]<<endl;
             if((temp_number[0] >= 0) ||(temp_number[1] >= 0))number[i]++          //注意。如果是子串是第一个字母开始的话,也要加1,因为substr返回的是字符串第一次出现的位置
         }
      }
   
      j=0;
      for(i=0;i<temp;i++)
         if(number[i]== n )
         {
             temp_length[j]=sub_string[i].length();
             j++;
         }
         if(j>0)
         {
         sort(temp_length,temp_length+j);
         cout<<temp_length[j-1]<<endl;
         }
         elsecout<<0<<endl;
   }
}