序列 ABAB對應字串集合

2021-05-12 13:57:48 字數 1553 閱讀 8828

問題

本題為 google 「top coder」850分例題。假設有這樣一種字串,它們的長度不大於 26,而且若乙個這樣的字串其長度為 m ,則這個字串必定由 a, b, c ... z中的前 m 個字母構成,同時保證每個字母出現且僅出現一次。比方說某個字串長度為 5 ,那麼它一定是由 a, b, c, d, e 這 5 個字母構成。一旦長度確定,這個字串中有哪些字母也就確定了,唯一的區別就是這些字母的前後順序而已。

現在我們用乙個由大寫字母 a 和 b 構成的序列來描述這類字串裡各個字母的前後順序:如果字母 b 在字母 a 的後面,那麼序列的第乙個字母就是 a (after),否則序列的第乙個字母就是 b (before);如果字母 c 在字母 b 的後面,那麼序列的第二個字母就是 a ,否則就是 b;如果字母 d 在字母 c 的後面,那麼 ……

不用多說了吧?直到這個字串的結束。

這規則甚是簡單,不過有個問題就是同乙個 ab 序列,可能有多個字串都與之相符,比方說序列 「aba」,就有 「acdb」、「cadb」等等好幾種可能性。說的專業一點,這乙個序列實際上對應了乙個字串集合。

那麼現在問題來了:給你乙個這樣的 ab 序列,問你究竟有多少個不同的字串能夠與之相符?或者說這個序列對應的字串集合有多大?注意,只要求個數,不要求列舉所有的字串。

分析在給定的 「ababb…」序列中,計算 1~n級的情況 (n=序列長度 ),規則為「對映」。在本題目中,我們並不需要關心每級中包含元素是什麼,而在於元素的個數。

假設現需要計算序列 「abbaa」,0級只對映乙個字串 「a」,並且 a在 0位置; 1級的時候,序列字元為 『a』,說明 b在 a後面,只能對映乙個字串 「ab」,b在 1位置; 2級的時候,序列字元為 『b』,說明 c在 b前面,能夠對映 「cab」, 「acb」,分別在 0、1位置。以此類推,每級對映字串數量計算如下表: 

由上表可以看出,對於每一級的情況,我們需要記錄兩個資訊:

本級能夠影射的字串數量;

最大字元所在位置(因為後序 ab序列只關心最大字元)。

綜合起來,就是需要按照最後字元所在位置的不同,分別記錄對映字串的數量。

解法按照分析思路,可以設定兩個雜湊表,乙個記錄 l級資料,乙個用來儲存 l+1級資料,計算一次後交換,**如下:

for (int i = 1; i < n; i++)

}var temp = dic1; dic1 = dic2; dic2 = temp;

dic2.clear();//交換兩個字典

}

其中:

string ab = abab序列

n = ab.length + 1;//對映的字串長度為 "abab..."長度 + 1

dic1 = new dictionary(n);//key=字元出現的位置 value=字串數量

dic2 = new dictionary(n);

初始化 dic1.add(0, 1);

討論在本題目中,由於只需要記錄每級元素的數量,「分級組合(排列)法」非常有效。後續應用中,我們還將看到類似例子。 

序列 字串

序列的基本操作 索引 分片 乘法 判斷成員資格 求長度 取最大最小值 對字串都同樣適用 字串是不可以改變的,沒有賦值 擴充套件這類操作 grade 87.6 str cc grade is 1f print str grade cc grade is 87.6 s plus s equals s 1...

字串操作集合

開發中對字串操作太多了,有著一系列方法,注 該文會隨著遇到問題而更新!1.substring 擷取 string stringsta hello word substring int x 指定開始位置,到字串結束 system.out.printl stringsta.substring 1 列印 ...

字串的集合

給定乙個字串的集合,格式如 要求將其中交集不為空的集合合併,要求合併完成後的集合之間無交集,例如上例應輸出,include include define size 5 int mlen 0 初始化各字串集的hash int inithash int hash,char p 從hash還原字串 voi...