Trie樹沉思錄(1)

2021-06-21 21:20:10 字數 2789 閱讀 3618

發現自己已經很久沒有寫解題報告了,很大一部分是因為懶,做完題之後不想再怎樣了~不過最近發現寫解題報告確實是有好處的,一方面可以複習,一方面可以梳理。還有就是可以給自己的歲月留下一點什麼東西~今天是五一勞動節,就應該要勞動!我要重新著手寫我的部落格了~

最近幾個星期都在研究字串,有點難,不過到現在為止trie數學得還算是有那麼點意思,寫篇博文來記錄一下!

(關於trie數是什麼東西我就不想寫了,我只寫我個人的一些思考)

trie樹通過共享字首來達到了節約記憶體的目標,十分的強大!關於他的實現大概有兩種:指標和二維陣列!我自己學的是白書上面的二維陣列。關於兩種的區別,據航姐姐說,對於題目只有一組測試資料的,那種都可以,對於有多重測試資料的,二維陣列比較好,以為在初始化比較的方便!接下來我具體地說一下二維陣列的實現細節!

二維陣列的實現個人覺得非常的強大!他充分利用了二維資料的各個部分進行資料儲存!我們假設乙個二維陣列ch[i][j] = k,那麼他的各部分的意思解釋如下:

i :當前節點的父節點的編號

j:當前節點的字元對應的數字的值;

k:當前節點的編號

為了記錄當前節點是否為單詞的結尾,我們引入了乙個新的陣列val,如果當前節點是單詞的結尾,值為1,否則為0,這樣我們就可以非常高效的判斷某乙個單詞的結尾了~

對於插入和尋找的細節,我打算在**中注釋給大家~

接下來我們來看幾道題:

hdoj 1251:

經典的入門題:

給你一堆單詞,然後後面給一些字首,問你以這些字首為開頭的單詞有多少個?

#include #include #include #define n 26

#define m 1000000

using namespace std;

int ch[m][n];//trie樹

int val[m];//記錄當前的節點是否為單詞的結尾

int sub[m];//記錄以當前節點為字首的單詞的次數

int allnode;//節點總數

void initial( )

int trans( char c )

void insert( char *s, int v )

curnode = ch[curnode][c];//不管用不用新建節點,都要更新父節點

sub[curnode]++;//放在上一句的後面是為了避免根節點

}val[curnode] = v;//最後跳出迴圈的curnode和allnode一定相等,將乙個非零的值付給最後乙個節點的val陣列

//printf( "w" );

}int find( char *s )//尋找過程與插入十分地接近

else

//該迴圈是為了找到是否存在當前的字首,如果存在,找出返回以該字首的的最後乙個字元的sub陣列的值就是以該字首為開始的單詞數

}//printf( "w" );

return sub[curnode];

}int main()

; initial();

int i = 1;

while( gets( str ) && str[0] )

//find( str );

while( gets( str ) )

}

hdoj 1671 :

給你一堆**號碼,如果裡面沒有任何乙個是另外乙個的字首,輸出yes,否則輸出no。

思路:每讀入乙個**號碼,插入字典樹,並進行尋找。這裡的尋找有兩種情況:長找短,短找長(即當前有可能是字首要找是有以之為字首的**號碼,或者是不是字首,即要在樹中找到是否有字首)。如果是第一種情況,只要在發生失配的時候判斷當前的節點是否為結尾即可;第二種情況,只要完全匹配,這說明存在以當前號碼為字首的的號碼~

有點囉嗦,看**:

#include #include #include #include #include #define n 500000

#define m 10

#define cj -1

using namespace std;

int ch[n][m];

int val[n];

int allnode;

void initial()

void insert( char *s, int v )

cu***ther = ch[cu***ther][s[i]-'0'];

}val[cu***ther] = v;

}int find( char *s )//false means no,

else

}else

}if( sub == len )

else

}int main()

; int t;

scanf( "%d", &t );

getchar();

//start:

while( t-- )

;bool no = false;

scanf( "%d", &num );

//cout << num << endl;

getchar();

initial();

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

else}}

if( no )

else

//cout << "yes" << endl;

}return 0;

}

本來還做了另一道題的,不過一直wa,也不知道是為什麼?爭取今天把它a了~

那就先這樣吧~

這三天對我很重要!!!



C 沉思錄 控制代碼1

1 在 c 沉思錄 類中,使用了 類,存在問題 a 複製,每次建立乙個副本,這個開銷有可能很大 b 有些物件不能輕易建立副本,比如檔案 2 怎麼解決這個問題?使用引用計數控制代碼,對動態資源封裝,控制代碼包含指標,多個控制代碼可以指向同乙個物件。複製的時候,只是複製控制代碼的指標。3 使用引用計數控...

C 沉思錄 控制代碼類1

看了下 c 沉思錄 第六章的內容介紹的是控制代碼第一部分,採用引用計數器的方式減少記憶體的拷貝 動手敲了下 加深點印象,加了點注釋 class point point int x,int y xval x yval y int x const int y const point x int xv p...

足球沉思錄

本部落格用於記錄我平時踢球的反思和總結。也許聽起來有點怪異 只聽過寫學習總結或工作總結的,你踢個球還寫什麼總結?踢球不就圖個開心嗎?我以前的想法也是這樣,只把踢球當做鍛鍊身體 放鬆身心的一種活動,踢得開心就行了,而不太在意自己踢得怎樣 存在什麼問題和怎麼改進等等。直到上個月有次週三晚上踢球,我被換到...