标签:
最小表示法:当给定一个字符串时,求它最小表示的情况,比如:baab 最小表示情况为: aabb 即把第二位置的a变成第一个位置。
最大表示法:比如 abcd 最大应为:dabc 基本概念和最小表示法相同。
时间复杂度:o(n)
应用:比较两个环形串是否是同一字符串、判重、判同分异构等。
方法:使用两个指针(或者两个变量模拟指针)分别从字符串的0、1位置开始扫,再设置一个跳跃标记k,即当两个指针指向同一大小的字符串时,可以跳跃至不相等处。然后,通过两个指针指向字符串大小进行字符串的迁移,直至到字符串末尾。
注意:因为扫的过程中,有可能会出界,所以,有两个方法解决这种情况。
1.在字符串s后面再加一个s
2.当越界的时候,回到起始位置。
前者方便一些,也快一些。
代码如下:
1 int findsmallsub(char *s) 2 { 3 int i = 0,j = 1,k = 0; //i,j,为指针,k为判重 4 int len = strlen(s); 5 strcpy(s2,s); 6 strcat(s,s2); //作用是:s=s+s 7 while(i<len&&j<len) 8 { 9 k=0; 10 while(k<len&&(s[i+k]==s[j+k])) 11 k++; 12 if(k>=len) 13 break; 14 if(s[i+k]>s[j+k]) //如果i+k处字符比j+k处大 15 i=max(i+k+1,j+1); //则i要像右移动,移动位置取两者大的位置+1 16 else 17 j=max(i+1,j+k+1); 18 } 19 return min(i,j); //返回最小位置 20 }
最大表示法:把14行的大于号改成小于即可。
方法二的代码:
1 int smallest(char *s) 2 { 3 int i=0,j=1; 4 int len = strlen(s); 5 int k=0; 6 while(i<len&&j<len&&k<len) 7 { 8 if(k==len)break; 9 if(i==j) j++; 10 int ni=i+k,nj=j+k; 11 if(ni>=len) ni-=len; 12 if(nj>=len) nj-=len; 13 if(s[ni]>s[nj]) 14 { 15 i+=k+1; 16 k=0; 17 } 18 else if(s[ni]<s[nj]) 19 { 20 j+=k+1; 21 k=0; 22 } 23 else k++; 24 } 25 return i; 26 }
标签:
原文地址:http://www.cnblogs.com/ikids/p/4658662.html