前言
不知道大家在做題時有沒有遇到過“字符串旋轉”的題目,很多人可能沒有思路,這里我不具體講解單一的題目,而是展現一個“彈幕滾動”的示例,相信大家看懂后就能做出“字符串旋轉”的題了!
技術名詞解釋
1.什么是“字符串旋轉”??
舉個例子:給定字符串“abcdef”,左旋一個單位就是“bcdefa”,兩個就是“cdefab”,右旋同理。
2.何為彈幕滾動?
彈幕滾動就是基于字符串旋轉的原理,只不過是持續進行旋轉罷了,比如“abcdef”緊接著的是“bcdefa”……每次顯示都會覆蓋上次顯示的內容(用到回車符),接下來我們主要介紹從右向左滾動的實現
整體架構思路
1.正常遍歷字符串
給定一個字符串,我們來看一下正常遍歷的代碼是怎樣的:
int main()
{char str[] = "da jia hao ,wo shi xxx";int len = strlen(str);int i;for (i = 0; i < len; i++){putchar(str[i]);}return 0;
}
大家應該都對這段代碼沒什么問題,那就應該知道這段代碼是從字符串的第一個元素開始打印的,要想滾動顯示,下一次就應該從第二個元素開始打印吧,并且首元素還要放在最后一位,第三次是第三個元素打頭,末尾放第二元素……要想實現這種流程,我們不妨再借助一位變量的幫助,這就有了我們的第二個思路
2.另創變量cnt,打頭元素靠他變,末尾元素照不誤
int i;
int cnt = 0;
char str[] = "da jia hao, wo shi xxx";
int len = strlen(str);for (i = 0; i < len; i++){if (cnt + i < len)putchar(str[cnt + i]);elseputchar(str[cnt + i - len]);}
? 分析一下代碼,在遍歷過程中,如果cnt+i沒有超出最大下標len-1,那么所要顯示的元素下標便是cnt+i,但如果大于等于len,cnt+i就不可能作為數組下標了吧,因為會越界,但是沒關系,我們最后要顯示的是本次所顯示的開頭元素之前的元素,所以最后要顯示的元素下標是cnt+i-len,當然,現在我們的cnt是0,所以跟之前的只有i的情況沒啥區別,但只要當cnt=1時,是不是就是從第二個元素開始遍歷了呢,cnt=2時是從第三個開始,以此類推……
? 列舉一下看看:假設字符串長度為5(abcde),當cnt=1時,i從0到4遞增,當i=0,1,2,3時,只靠if語句就可以顯示(bcde)了,當i=4時,cnt+i等于5,該走else語句了,顯示的是cnt+i-len也就是0下標,因此最后一個元素就是首元素,這不就達成了預期嗎
OK,思路到這里沒問題吧,接下來就要考慮如何讓cnt變化了,也就是有了思路三。
3.cnt背后當大佬,讓誰出場誰出場
cnt該怎么變化呢,我們知道彈幕滾動的關鍵變化就在開頭和結尾,第一次以字符串的首元素為開頭,第二次以次元素開頭……不知道大家有沒有發現,每當顯示開頭字符的時候,i的值必然為0,而要顯示的首字符又是依次遞增的,那是不是只要讓cnt依次遞增,首字符也就依次往后排了呢,OK,就是這個思路往下走!cnt初始值是0,依次遞增下去,直到cnt=len-1時,也就是最后一個元素下標時,str【cnt+i】(i=0)就是字符串的最后一個字符,如果想再來一遍滾動,就讓cnt重新歸0,并重復上述過程即可。代碼如下:
int main()
{int i;int cnt = 0;char str[] = "da jia hao, wo shi xxx";int len = strlen(str);while (1){putchar('\r');for (i = 0; i < len; i++){if (cnt + i < len)putchar(str[cnt + i]);elseputchar(str[cnt + i - len]);}Sleep(500);if (cnt < len - 1)cnt++;elsecnt = 0;}return 0;
}
技術細節
1.代碼補充
? 最后代碼示意圖中采用了無限循環“字幕滾動”的形式,為了避免“字符滿天飛”的現象,用了‘\r’,每次顯示彈幕但會覆蓋掉上次的彈幕,因此最終屏幕上也只有一行字符,同時為了體現出“滾動”的效果,中間用了Sleep函數延緩程序短暫時間,也就是每次顯示完一行彈幕后,都會延緩0.5秒才顯示下一次的彈幕
2.關于彈幕從左向右滾動
無需改變過多代碼,只需將下面的if else語句稍加修改即可
int main()
{int i;int cnt = 0;char str[] = "da jia hao, wo shi xxx";int len = strlen(str);while (1){putchar('\r');for (i = 0; i < len; i++){if (cnt + i < len)putchar(str[cnt + i]);elseputchar(str[cnt + i - len]);}Sleep(500);if (cnt =0)cnt=len-1;elsecnt --;}return 0;
}
小結
學好字幕滾動,字符串旋轉都是小菜!