字串排序

2021-08-02 12:45:24 字數 1896 閱讀 3671

時間限制:

2000

ms  |  記憶體限制:

65535

kb 難度:

描述 給出乙個長為len的字串str,把字串的首尾相連,然後以每個字元為起點,順時針遍歷每個字元,得到len個新的字串,然後把這len個字串按照字典序從小到大的順序進行排序,取出排完序後的每個字串的最後乙個字元,形成乙個新的字串s。求s。

如下圖。假設str=「topcoder」,則得到的新的字串有

topcoder, opcodert, pcoderto, codertop, odertopc, dertopco, ertopcod, rtopcode,

按字典序排完序為

codertop, dertopco, ertopcod, odertopc, opcodert, pcoderto, rtopcode, topcoder,

則取出每個字串最後乙個字元之後形成的字串為podctoer,即s = 「podctoer」。

輸入多組測試資料。

每組測試資料報括乙個字串,長度不超過100000。字串由所有可列印字元組成。

輸出每組資料佔一行,輸出s。

樣例輸入

topcoder

i love you

樣例輸出

podctoer

ievu yloo

解:
以topcoder為例

首先先翻倍topcodertopcoder,那麼我們實際上是要找長度為len的子串的字典序排序結果,至於是在前半區還是後半區,加乙個判斷即可。

現在是如何解決長度為len,解決方法就是不管它。。。舉個例子

兩個長度為len的子串1,子串2,它的實際字尾組成長子串1,長子串2,那麼有以下3種情況

1、子串1 > 子串2,那麼顯然長子串1 > 長子串2

2、子串1 < 子串2,那麼顯然長子串1 < 長子串2

3、子串1 = 子串2 ,那麼長子串1與長子串2的結果不確定

綜上,如果我們直接對所有長子串進行字典序排序的話,對應的子串的字典序排序結果也是正確的,只是不穩定,然而不穩定對本題的結果並沒有影響。。求字典序的工作就交給字尾陣列的sa啦

下面附上c++的**:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define inf 2147483647

#define linf 9223372036854775807ll

#define ll long long

using namespace std;

const int maxn = 200010;

void da(int str, int sa, int rank, int n, int m);

int t1[maxn], t2[maxn], c[maxn];

int dstr[maxn], sa[maxn], rank[maxn];

char str[maxn],ans[maxn];

int main()

ans[len] = '\0';

printf("%s\n", ans); }

return 0; }

bool cmp(int *r, int a, int b, int l)

void da(int str, int sa, int rank,  int n, int m)

int k = 0;

n--;

for (i = 0; i <= n; i++) rank[sa[i]] = i;

return; }

字串 字串排序

頻率統計 將頻率轉換為索引 資料分類 回寫頻率統計 統計每個字元出現的次數 將頻率轉換為索引 確定不同字元首位置 從右到左檢查檢查鍵中的字元 public class lsd public class msd public static void sort string a private stat...

《演算法》 字串 字串排序

輸入字串和字串對應的組別 組別也是字串的鍵 在滿足組別有小到大排序的情況下,將字串按字母順序排序 第一步,記錄組別的頻率 為了得到某個字串在排序後的範圍,比如組別2肯定在組別1後面,在組別3前面,把每個組別有多少個人記錄下來,方便我們定位 第三步,分類 該組別的位置起點 向後挪一位 因為當前位被用了...

字串排序

從鍵盤輸入10個學生的姓名和成績,請按字典序排列學生的姓名並輸出 姓名和成績對應關係保持不變 輸入共11行,前10行每行是乙個學生的姓名,最後一行是10個用空格分開的整數表示對應的10個學生成績。輸出姓名按字典序排列後的學生姓名和成績,共10行,每個學生的姓名和成績佔一行,姓名和成績間用逗號分開。b...