hdu 3374 String Problem (kmp+最大最小標記法)

來源:互聯網
上載者:User

標籤:style   blog   http   color   os   io   ar   div   

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=3374

題目大意:輸出最大和最小的是從哪一位開始的,同時輸出最小迴圈節的個數。

這裡簡單介紹對字串最小表示的方法:

(1)  利用兩個指標p1, p2。初始化時p1指向s[0], p2指向s[1]。

 

(2)  k = 0開始,檢驗s[p1+k] 與 s[p2+k] 對應的字元是否相等,如果相等則k++,一直下去,直到找到第一個不同,(若k試了一個字串的長度也沒找到不同,則那個位置就是最小表示位置,演算法終止並返回)。則該過程中,s[p1+k] 與 s[p2+k]的大小關係,有三種情況:

     (A). s[p1+k] > s[p2+k],則p1滑動到p1+k+1處 --- 即s1[p1->p1+k]不會是該迴圈字串的“最小表示”的首碼。 k置為0

 

     (B). s[p1+k] < s[p2+k],則p2滑動到p2+k+1處, k置為0

 

     (C). s[p1+k] = s[p2+k],則 k++; if (k == len) 返回結果。

 

    注:這裡滑動方式有個小細節,若滑動後p1 == p2,將正在變化的那個指標再+1。直到p1、p2把整個字串都檢驗完畢,返回兩者中小於 len 的值。

(3)   如果 k == len, 則返回p1與p2中的最小值

 

最大和最小表示完全類似,簡單的改變一下即可。下面詳見代碼。

 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 int next[1000010],len,t; 6 char ch[1000010]; 7  8 void get_next() 9 {10     int i=0,j=-1;11     next[0]=-1;12     while (i<len)13     {14         if (j==-1||ch[i]==ch[j])15         {16             i++;17             j++;18             next[i]=j;19         }20         else21             j=next[j];22     }23 }24 25 int Min_(char s[],int len)26 {27     int p1=0,p2=1,k=0;28     while (p1<len&&p2<len&&k<len)29     {30         t=s[(p1+k)%len]-s[(p2+k)%len];31         if (t==0)32             k++;33         else34         {35             if (t>0)36                 p1=p1+k+1;37             else38                 p2=p2+k+1;39             if (p1==p2)40                 p2++;41             k=0;42         }43     }44     return min(p1,p2);45 }46 47 int Max_(char s[],int len)48 {49     int p1=0,p2=1,k=0;50     while (p1<len&&p2<len&&k<len)51     {52         t=s[(p1+k)%len]-s[(p2+k)%len];53         if (t==0)54             k++;55         else56         {57             if (t>0)58                 p2=p2+k+1;59             else60                 p1=p1+k+1;61             if (p1==p2)62                 p2++;63             k=0;64 65         }66     }67     return p1<p2?p1:p2;68 }69 70 int main()71 {72     while(~scanf("%s",ch))73     {74         len=strlen(ch);75         get_next();76         int Max=Max_(ch,len);77         int Min=Min_(ch,len);78         //cout<<Max<<Min<<endl;79         int sum=0;80         if(len%(len-next[len])==0)81             sum=len/(len-next[len]);82         else83             sum=1;84         printf ("%d %d %d %d\n",Min+1,sum,Max+1,sum);85     }86     return 0;87 }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.