前言
不知道大家在做题时有没有遇到过“字符串旋转”的题目,很多人可能没有思路,这里我不具体讲解单一的题目,而是展现一个“弹幕滚动”的示例,相信大家看懂后就能做出“字符串旋转”的题了!
技术名词解释
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;
}
小结
学好字幕滚动,字符串旋转都是小菜!