演算法的樂趣c/c++ —— 1.2.3入門習題 —連結串列
宣告:摘選自“ 演算法競賽入門經典(第2版)”作者: 劉汝佳 / 陳鋒 ISBN:9787302291077
破損的鍵盤(又名:悲劇文字)
你有一個破損的鍵盤。 鍵盤上的所有鍵都可以正常工作,但有時Home鍵或者End鍵會自動按下。 你並不知道鍵盤存在這一問題,而是專心地打稿子,甚至連顯示器都沒開啟。 當你開啟顯示器之後,展現在你面前的是一段悲劇的文字。 你的任務是在開啟顯示器之前計算出這段悲劇文字。輸入包含多組資料。 每組資料佔一行,包含不超過100000個字母、 下劃線、 字元“[”或者“]”。 其中字元“[”表示Home鍵,“]”表示End鍵。 輸入結束標誌為檔案結束符(EOF)。 輸入檔案不超過5MB。 對於每組資料,輸出一行,即螢幕上的悲劇文字。
樣例輸入:
This_is_a_[Beiju]_text
[[]][][]Happy_Birthday_to_Tsinghua_University
樣例輸出:
BeijuThis_is_a__text
Happy_Birthday_to_Tsinghua_University
解題思路
我們利用連結串列來實現這個操作,其實用陣列也可以,只要遇到 '[' 就在陣列去前面插入接下來的資料就可以了,但是利用陣列進行插入操作極其消耗時間。而連結串列就沒有這個問題,因為連結串列每個元素除了儲存值以外,還會儲存下一個元素的地址。我們建立一個數組 next [ ] 來存放下一個元素的地址(這裡的地址指的是在字串陣列 s 裡面的索引號)。next [0] 存放需要列印的第一個元素,因為 ’[ ' 的存在,next [0]的值在不斷變化。以 This_is_a_[Beiju]_text 為例:
未遇到 ’[ ' 之前,next [ i ] 記錄的是下一個字元的地址,遇到 ’[ ' 之後,將next [0] 重置為 ’[ ' 下一個元素的索引,並同時記錄此時的 i 值,為了遇到 ']' 之後可以快速回到接下來的位置。因為 next [0] 記錄的是下一個元素的索引值,所以s要從 s+1開始儲存元素。
#include<iostream> #include<cstring> using namespace std; int main() { char s[100]; cin >> s+1; int next[100], last=0; int len = strlen(s+1); next[0] = 1; for(int i=1; i<=len; i++) { if(s[i] == '[') {next[0]=i+1; next[i]=i+1; last=i;} else if(s[i] == ']') {next[i] = 1;next[last]=i+1;} else next[i] = i+1; } for(int i=next[0]; i!=0; i=next[i]) { if(s[i]!='[' && s[i] !=']') cout << s[i]; } return 0; }