文字列表記は最大最小
タイトル:開始された最大値と最小出力を表すが、出力の数
良好な需要の数は、ループ部はKMPの次の配列によって直接得ることができ、確実に文字列の周期部です。
最大値と最小値の表現のために、文字列が連続辞書最大値または最小値を得るために、回転しています。
最小の文字列表現方法を探しています
1.二つのポインタを使用してP1、P2を。P1初期点S [0] 、P2の点S [1] 。
2. K = 0を開始検査S [P1 + K]とS [P2 + K]等しいkは++、ダウンしている場合は、文字列場合、最初は異なる、(試みkとなるまでの文字に対応するが、等しいです長さは、その最も小さい位置)位置、アルゴリズムは終了し、リターンを示している、異なる見つけることができませんでした。プロセスでは、S [K + P1]とS [P2 + k]の大小関係は、3つのケースがあります。
- (A)。S [P1 + K]> S [K + P2] 、次いでP1にスライドされ、P1 + K + 1 ···で即ち* S1 [P1-> P1 + K] ** ありません
サイクルは、文字列「最小平均」接頭辞です。kが0に設定されています
- (B)S [P1 + K] <S [P2 + K] 、その後のP2にスライドK + P2 + 1において、Kは0に設定されています
- (C)S [P1 + K] = S [K + P2]次に、K ++;(K == lenがあれば ) 結果を返します。
注:この方法をスライドであれば後はほとんど詳細スライドがあり、P1 == P2再び+1両手を変更します。P1までは、p2が検査の文字列全体が、戻り値は、両方のLEN未満です。
- 場合K == lenは、P1、P2は最小リターンがあります
実際には、最大の表現として、それが要した時間の変化の大きさは、あなたが内部の関数を書くことができます。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX=1000000+10;
char str[MAX];
int nex[MAX];
/*
比找最小表示法,相当于找着一个字符串a,再找一个一直循环比较
如果他是最小的,就会一直增加比较,直到长度为len则返回
如果出现i和j相等的情况,j加1最后返回小的那一个就行
*/
void Get_nex(int len){
int i=0,j=-1;
nex[0]=-1;
while(str[i]){
if(j==-1||str[i]==str[j]){
i++;j++;
nex[i]=j;
}else
j=nex[j];
}
}
int min_max_express(char *s,int len,bool flag){//最小表示法和最大表示法写到一块儿了
int i=0,j=1,k=0;
while(i<len&&j<len&&k<len){//一次就能够找着
int t=s[(j+k)%len]-s[(i+k)%len];//比较两个字符
if(t==0)k++;//相等,就后移比较下一个字符
else{
if(flag){//最小表示法
if(t>0)j+=k+1; //+(k+1)相当于直接把相等的跳过
else i+=k+1;
}else{//最大表示法
if(t<0) j+=k+1;
else i+=k+1;
}
if(i==j)j++;
k=0;
}
}
return min(i,j);
}
int main(){
while(scanf("%s",str)!=EOF){
int len=strlen(str);
int min_express=min_max_express(str,len,true);
int max_express=min_max_express(str,len,false);
Get_nex(len);
int ans=len%(len-nex[len])?1:len/(len-nex[len]);
printf("%d %d %d %d\n",min_express+1,ans,max_express+1,ans);//因为从0开始的,最大最小项+1
}
return 0;
}