DFA算法C#實現(xiàn)

試了一下顽照,初始化一個一萬九千多行的文本大概需要40毫秒狼荞,然后在一個大約二萬字的文本內(nèi)搜索100多個關(guān)鍵詞(隨機插入測試的辽装,話說處理這個測試文本還花了一些功夫,第一版的隨機插入相味,時不時就會插入到前面插入的關(guān)鍵詞中間去拾积,導(dǎo)致匹配出來的數(shù)量老是不對),只需要7毫秒丰涉。

復(fù)制代碼

? 1? ? /// <summary>

? 2? ? /// 過濾詞DFA算法實現(xiàn)

? 3? ? /// </summary>

? 4? ? public class ForbiddentWordLibrary

? 5? ? {

? 6? ? ? ? /// <summary>

? 7? ? ? ? /// 用分行過濾詞文件來初始化過濾詞庫

? 8? ? ? ? /// </summary>

? 9? ? ? ? /// <param name="path">文件路徑</param>

10? ? ? ? public ForbiddentWordLibrary( string path )

11? ? ? ? {

12? ? ? ? ? ? try

13? ? ? ? ? ? {

14? ? ? ? ? ? ? ? words = new HashSet<string>();

15? ? ? ? ? ? ? ? using( var stream = new StreamReader( path, Encoding.UTF8 ) )

16? ? ? ? ? ? ? ? {

17? ? ? ? ? ? ? ? ? ? while( !stream.EndOfStream )

18? ? ? ? ? ? ? ? ? ? {

19? ? ? ? ? ? ? ? ? ? ? ? words.Add( stream.ReadLine().Trim() );

20? ? ? ? ? ? ? ? ? ? }

21? ? ? ? ? ? ? ? }

22? ? ? ? ? ? ? ? InitLibrary();

23? ? ? ? ? ? }

24? ? ? ? ? ? catch( Exception ex )

25? ? ? ? ? ? {

26? ? ? ? ? ? ? ? throw ex;

27? ? ? ? ? ? }

28? ? ? ? }

29

30? ? ? ? /// <summary>

31? ? ? ? /// 找到輸入字符串內(nèi)所有敏感詞

32? ? ? ? /// </summary>

33? ? ? ? /// <param name="input"></param>

34? ? ? ? /// <returns></returns>

35? ? ? ? public List<string> GetAllForbiddenWords( string input )

36? ? ? ? {

37? ? ? ? ? ? List<string> result = new List<string>();

38? ? ? ? ? ? for( int i = 0; i < input.Length; i++ )

39? ? ? ? ? ? {

40? ? ? ? ? ? ? ? int length = SearchFW( input, i );

41? ? ? ? ? ? ? ? if( length > 0 )

42? ? ? ? ? ? ? ? {

43? ? ? ? ? ? ? ? ? ? result.Add( input.Substring( i, length ) );

44? ? ? ? ? ? ? ? ? ? i = i + length - 1;

45? ? ? ? ? ? ? ? }

46? ? ? ? ? ? }

47

48? ? ? ? ? ? return result;

49? ? ? ? }

50

51? ? ? ? /// <summary>

52? ? ? ? /// 搜索輸入的字符串拓巧,查找所有敏感詞,找到則返回敏感詞長度

53? ? ? ? /// </summary>

54? ? ? ? /// <param name="input">輸入字符串</param>

55? ? ? ? /// <param name="beginIndex">查找的起始位置</param>

56? ? ? ? /// <returns></returns>

57? ? ? ? private int SearchFW( string input, int beginIndex )

58? ? ? ? {

59? ? ? ? ? ? bool flag = false;

60? ? ? ? ? ? int len = 0;

61? ? ? ? ? ? Hashtable ht = lib;

62? ? ? ? ? ? for( int i = beginIndex; i < input.Length; i++ )

63? ? ? ? ? ? {

64? ? ? ? ? ? ? ? var c = input[ i ];

65? ? ? ? ? ? ? ? var obj = ht[ c.ToString() ];

66? ? ? ? ? ? ? ? if( obj == null )

67? ? ? ? ? ? ? ? ? ? break;

68? ? ? ? ? ? ? ? else

69? ? ? ? ? ? ? ? {

70? ? ? ? ? ? ? ? ? ? len++;

71? ? ? ? ? ? ? ? ? ? ht = (Hashtable)obj;

72? ? ? ? ? ? ? ? ? ? if( (int)ht[ "IsEnd" ] == 1 )

73? ? ? ? ? ? ? ? ? ? ? ? flag = true;

74? ? ? ? ? ? ? ? }

75? ? ? ? ? ? }

76

77? ? ? ? ? ? if( !flag )

78? ? ? ? ? ? ? ? len = 0;

79

80? ? ? ? ? ? return len;

81? ? ? ? }

82

83? ? ? ? /// <summary>

84? ? ? ? /// 初始化詞庫結(jié)構(gòu)

85? ? ? ? /// </summary>

86? ? ? ? private void InitLibrary()

87? ? ? ? {

88? ? ? ? ? ? lib = new Hashtable( words.Count );

89? ? ? ? ? ? var tmp = lib;

90? ? ? ? ? ? foreach( string k in words )

91? ? ? ? ? ? {

92? ? ? ? ? ? ? ? for( int i = 0; i < k.Length; i++ )

93? ? ? ? ? ? ? ? {

94? ? ? ? ? ? ? ? ? ? var c = k[ i ].ToString();

95? ? ? ? ? ? ? ? ? ? if( tmp.ContainsKey( c ) )

96? ? ? ? ? ? ? ? ? ? {

97? ? ? ? ? ? ? ? ? ? ? ? tmp = (Hashtable)tmp[ c ];

98? ? ? ? ? ? ? ? ? ? }

99? ? ? ? ? ? ? ? ? ? else

100? ? ? ? ? ? ? ? ? ? {

101? ? ? ? ? ? ? ? ? ? ? ? var nht = new Hashtable();

102? ? ? ? ? ? ? ? ? ? ? ? nht.Add( "IsEnd", 0 );

103? ? ? ? ? ? ? ? ? ? ? ? tmp.Add( c, nht );

104? ? ? ? ? ? ? ? ? ? ? ? tmp = nht;

105? ? ? ? ? ? ? ? ? ? }

106

107? ? ? ? ? ? ? ? ? ? if( i == k.Length - 1 )

108? ? ? ? ? ? ? ? ? ? {

109? ? ? ? ? ? ? ? ? ? ? ? if( tmp.ContainsKey( "IsEnd" ) )

110? ? ? ? ? ? ? ? ? ? ? ? ? ? tmp[ "IsEnd" ] = 1;

111? ? ? ? ? ? ? ? ? ? ? ? else

112? ? ? ? ? ? ? ? ? ? ? ? ? ? tmp.Add( "IsEnd", 1 );

113? ? ? ? ? ? ? ? ? ? }

114? ? ? ? ? ? ? ? }

115? ? ? ? ? ? ? ? tmp = lib;

116? ? ? ? ? ? }

117? ? ? ? }

118

119? ? ? ? /// <summary>

120? ? ? ? /// 原始過濾詞數(shù)據(jù)集

121? ? ? ? /// </summary>

122? ? ? ? private HashSet<string> words;

123? ? ? ? /// <summary>

124? ? ? ? /// 過濾詞庫

125? ? ? ? /// </summary>

126? ? ? ? private Hashtable lib;

127? ? }?

亞馬遜測評 www.yisuping.com

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末一死,一起剝皮案震驚了整個濱河市肛度,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌投慈,老刑警劉巖承耿,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冠骄,死亡現(xiàn)場離奇詭異,居然都是意外死亡加袋,警方通過查閱死者的電腦和手機凛辣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來职烧,“玉大人蟀给,你說我怎么就攤上這事⊙舳椋” “怎么了跋理?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長恬总。 經(jīng)常有香客問我前普,道長,這世上最難降的妖魔是什么壹堰? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任拭卿,我火速辦了婚禮,結(jié)果婚禮上贱纠,老公的妹妹穿的比我還像新娘峻厚。我一直安慰自己,他們只是感情好谆焊,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布惠桃。 她就那樣靜靜地躺著,像睡著了一般辖试。 火紅的嫁衣襯著肌膚如雪辜王。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天罐孝,我揣著相機與錄音呐馆,去河邊找鬼。 笑死莲兢,一個胖子當著我的面吹牛汹来,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播改艇,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼收班,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了遣耍?” 一聲冷哼從身側(cè)響起闺阱,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎舵变,沒想到半個月后酣溃,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瘦穆,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年赊豌,在試婚紗的時候發(fā)現(xiàn)自己被綠了扛或。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡碘饼,死狀恐怖熙兔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情艾恼,我是刑警寧澤住涉,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站钠绍,受9級特大地震影響舆声,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柳爽,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一媳握、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧磷脯,春花似錦蛾找、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至架曹,卻和暖如春隘冲,著一層夾襖步出監(jiān)牢的瞬間闹瞧,已是汗流浹背绑雄。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留奥邮,地道東北人万牺。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像洽腺,于是被迫代替她去往敵國和親脚粟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359