当前位置:   article > 正文

scanf留下的那一片云彩

scanf留下的那一片云彩

【题目描述】

给出一个由O和X组成的串(长度为1~80),统计得分。每个O的得分为目前连续出现的O的个数,X的得分为0。例如,OOXXOXXOOO的得分为1+2+0+0+1+0+0+1+2+3。

输入第一行表示有n个字符串,后续是n行字符串。

【样例输入】

5

OOXXOXXOOO

OOXXOOXXOO

OXOXOXOXOXOXOX

OOOOOOOOOO

OOOOXOOOOXOOOOX

【样例输出】

10

9

7

55

30

【题目来源】

刘汝佳《算法竞赛入门经典  第2版》习题3-1 得分(Score, ACM/ICPC Seoul 2005, UVa1585)

【解析】

本题是一道得分累加问题,题目不难,只需定义两个变量:

①计数器cnt,用于计算已经连续出现的“O”的个数;

②累加器sum,用于计算串的得分。

思路就是对输入串的字符进行遍历,如果遇到“O”就cnt++,如果遇到“X”就将cnt重置为0,然后每次将cnt加到sum中即可。

1.用scanf输入字符串

  1. #include<stdio.h>
  2. char s[85];
  3. int main(){
  4. int n;
  5. char c;
  6. scanf("%d", &n);
  7. while(n--){
  8. int sum=0, cnt=0;
  9. scanf("%s", s);
  10. for(int i=0; i<strlen(s); i++){
  11. if('O'==s[i]) cnt++;
  12. else cnt=0;
  13. sum += cnt;
  14. }
  15. printf("%d\n", sum);
  16. }
  17. return 0;
  18. }

代码说明:

1.代码精简。for循环中的代码可以进一步精简,就是将cnt的自加与sum的累加合成一个语句,改后代码如下:

if('O'==s[i]) sum += ++cnt;

else cnt=0;

注意,因为要返回自加后的值,此时就需要用++cnt,不能用cnt++(关于二者的区别参见“找不到北的i++”一文https://blog.csdn.net/jjmhx/article/details/136995419)。

2.效率问题。你是否发现,代码中有一处写法效率低下。就是在“程序找茬:统计字符个数问题”一文中提到的“重复调用函数”问题,strlen函数放在for循环中会导致重复计算字符串的长度。解决方法就是预先将函数的值赋给一个变量,在for循环中直接用这个变量。

3.头文件缺失。在“程序找茬:统计字符个数问题”一文中已提到,不引用<string.h>头文件程序也能执行(只是会有警告),但是在Online Judge - Home网站中提交代码反馈错误。

如果因为这个问题丢分实属不值,所以还是乖乖加上该加的头文件吧。

2.用getchar输入字符

老金想着秀一下“编技”,打一开始就想用getchar读取字符,这样就用不着数组了,没想到输出了意想不到的结果。

最开始编的代码是只是针对一个字符串的情况,运行没有任何问题。代码如下:

  1. #include<stdio.h>
  2. int main(){
  3. char c;
  4. int sum=0, cnt=0;
  5. while((c=getchar())!='\n'){
  6. if('O'==c) cnt++;
  7. else cnt=0;
  8. sum += cnt;
  9. }
  10. printf("%d\n", sum);
  11. return 0;
  12. }

没想到改成多组字符串时出现了问题,代码如下:

  1. #include<stdio.h>
  2. int main(){
  3. int n;
  4. char c;
  5. scanf("%d", &n);
  6. while(n--){
  7. int sum=0, cnt=0;
  8. while((c=getchar())!='\n'){
  9. if('O'==c) cnt++;
  10. else cnt=0;
  11. sum += cnt;
  12. }
  13. printf("%d\n", sum);
  14. }
  15. return 0;
  16. }

运行结果:

居然刚输入数字5就直接输出了结果!什么情况?

经过调试老金搞明白了原因,问题出在了输入缓冲区。

执行到scanf("%d", &n)这条语句时,实际在键盘输入的是两个字符:一个是’5’,一是个换行符’\n’。 scanf函数只是读取了字符“5”,并没有读入换行符。所以这条语句执行完后,换行符还留在输入缓冲区。因此,getchar第一次读取的是换行符,循环条件不满足,直接输出sum的初始值0。

搞清原因,解决起来就好办了,在while((c=getchar())!='\n')前加一条语句把换行符读取掉就可以了。增加代码如下:

getchar(); //清空缓冲区的换行符

所以,在使用getchar()时要注意,如果前面使用了scanf函数,别忘了带走它留下的那片云彩。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/582115
推荐阅读
相关标签
  

闽ICP备14008679号