今天是元旦,開篇先祝福大家在新的一年心想事成,工作順利,開心生活每一天 。
看到【英雄會】上出現了微軟出的題目:幾個bing,題目內容如下:
本屆大賽由微軟必應詞典冠名,必應詞典(Bing Dictionary)是微軟推出的新一代英語學習引擎,里面收錄了很多我們常見的單詞,詳情請見:http://cn.bing.com/dict/?form=BDVSP4&mkt=zh-CN&setlang=ZH。但現實生活中,我們也經常能看到一些毫無規則的字符串,導致詞典無法正常收錄,不過,我們是否可以從無規則的字符串中提取出正規的單詞呢?
例如有一個字符串"iinbinbing",截取不同位置的字符‘b’、‘i’、‘n’、‘g’組合成單詞"bing"。若從1開始計數的話,則‘b’ ‘i’ ‘n’ ‘g’這4個字母出現的位置分別為(4,5,6,10) (4,5,9,10),(4,8,9,10)和(7,8,9,10),故總共可以組合成4個單詞”bing“。
咱們的問題是:現給定任意字符串,只包含小寫‘b’ ‘i’ ‘n’ ‘g’這4種字母,請問一共能組合成多少個單詞bing?
字符串長度不超過10000,由於結果可能比較大,請輸出對10^9 + 7取余數之后的結果。
最初的想法:分別記錄四個字符出現的位置編號,通過后者字符編號大於前者字符編號條件,循環遍歷得到符合條件的次數,但該算法的時間復雜度O(n4),實現絕對可以實現,但肯定行不通,改變策略。
分析:通過題面分析可知,是從字符串中取‘b’、‘i’、‘n’、‘g’四個字符進行排列組合,重新生成字符串”bing”的過程。但注意的是組合在一塊的序列是有一定規律的,序號是逐漸遞增的【(4,5,6,10) (4,5,9,10),(4,8,9,10)和(7,8,9,10)】,這就提供了一個先決條件:后者字符必須在前者字符存在的情況下進行計數和組合。算法復雜度為O(n).
做法:分別記錄b、bi、bin、bing生成的排列次數,后者次數=前者基礎次數+后者自身次數(例如:bi次數=b次數+bi自身次數)
以字符串"iinbinbing"為例,對字符串中字符進行遍歷:
① 分別用四個計數器來記錄組合
b |
bi |
bin |
bing |
0 |
0 |
0 |
0 |
② 當遍歷’i’時,b的計數為0,在沒有b存在的基礎上,bing是不可能出現的
b |
bi |
bin |
bing |
0 |
0 |
0 |
0 |
③ 當遍歷’i’時,b的計數為0,在沒有b存在的基礎上,bing是不可能出現的
b |
bi |
bin |
bing |
0 |
0 |
0 |
0 |
④ 當遍歷’b’時,bing是以b開始的,則b計數為1:
b |
bi |
bin |
bing |
1 |
0 |
0 |
0 |
⑤ 當遍歷’i’時,b的計數為1,在有b存在的基礎上,bi是可以出現的,則bi計數為1(b計數+bi當前計數):
b |
bi |
bin |
bing |
1 |
1 |
0 |
0 |
⑥ 當遍歷’n’時,i的計數為1,在有bi存在的基礎上,bin是可以出現的,則bin計數為1(bi計數+bin計數):
b |
bi |
bin |
bing |
1 |
1 |
1 |
0 |
⑦ 當遍歷’b’時,則b計數為2:
b |
bi |
bin |
bing |
2 |
1 |
1 |
0 |
⑧ 當遍歷’i’時,b的計數為2,在有b存在的基礎上,bi可能出現的次數為3(b計數+bi當前計數):
b |
bi |
bin |
bing |
2 |
3 |
1 |
0 |
⑨ 當遍歷’n’時,i的計數為2,在有bi存在的基礎上,bi可能出現的次數為4(bi計數+bin當前計數):
b |
bi |
bin |
bing |
2 |
3 |
4 |
0 |
⑩ 當遍歷’g’時,在有bin存在的基礎上,bing可能出現的次數為4(bin計數+bing當前計數):
b |
bi |
bin |
bing |
2 |
3 |
4 |
4 |
這樣就得到了bing字符串的組合方式有4種了,代碼實現如下:
using System; public class Test { public static int howmany(string s) { int bCount = 0; int biCount = 0; int binCount = 0; int bingCount = 0; for (int index = 0, length = s.Length; index < length; index++) { switch (s[index]) { case 'b': bCount = ++bCount % 1000000007; break; case 'i': biCount = biCount % 1000000007 + bCount; break; case 'n': binCount = binCount % 1000000007 + biCount; break; case 'g': bingCount = bingCount % 1000000007 + binCount; break;
} } return bingCount % 1000000007; }
//start 提示:自動閱卷起始唯一標識,請勿刪除或增加。 public static void Main() { Console.WriteLine(howmany("iinbinbing ")); } //end //提示:自動閱卷結束唯一標識,請勿刪除或增加。 }