单词长度试题的分析

题目要求:

你的程序要读入一行文本,其中以空格分隔为若干个单词,以.结束。你要输出每个单词的长度。这里的单词与语言无关,可以包括各种符号,比如it's算一个单词,长度为4。注意,行中可能出现连续的空格;最后的.不计算在内。

该题目有多种解法,那么根据现有知识(if-else和while)如何完成这个题目?

  1. 首先根据题目要求,计算单词的长度,以.结束,这时大家应该能想到while(ch != '.') 。再根据提示,字符使用scanf("%c",&c);一个一个的读入。
    2)然后题目要求计算每个单词的长度,以空格分隔为若干单词,假如我们就计算题目给出的样例:It's great to see you here.。
  • 首先需要定义整型变量count,存放单词的长度
  • 然后读入字符后,需要对字符进行判断是否为空格,如果字符不是空格,那么count++,如果是空格,则一个单词完结,打印出count的数,然后再对count清0,准备计算下一个单词的个数。若完成这些基本功能,代码长如下的样子:
int main (void)
{ 
	char c;
	int count=0;
	scanf("%c",&c);
	while(c != '.'){
		if(c==' '){
			printf("%d ",count);
			count=0;
			}
		else{
			count++;
		}	
		scanf("%c",&c);
	}
	return 0; 
}

单词长度试题的分析

  • 将输入样例输入后,输出结果能够正常显示出前四个单词的个数,但是最后一个单词的个数没有打印,分析程序,是因为最后一个数字没有打印时就退出循环,那么就需要在while结束后加上该最后一个单词长度的打印:
# include <stdio.h>
# include <math.h>
int main (void)
{ 
	char c;
	int count=0;
	scanf("%c",&c);
	while(c != '.'){
		if(c==' '){
			printf("%d ",count);
			count=0;
			}
		else{
			count++;
		}	
		scanf("%c",&c);
	}
	if(c=='.') printf("%d",count);
	return 0; 
}


运行输入样例,结果和PTA上的输出样例一模一样了~

单词长度试题的分析

当你异常兴奋的将代码提交到PTA上时,你会发现PTA上依然有错误:

单词长度试题的分析

PTA测试点错误问题的解决:

研究上图中pta的提示信息,程序没有考虑一些空格的情况,那么根据pta的提示一个一个的攻克:
1)首先是空句子的问题,比如只输入一个点是空句子,没有单词应该没有长度,就是没有任何输出(这一点我也是问过出题的翁恺老师才觉得合理),而我们的程序会输出一个0,首先要明白0是哪条语句输出的,其实是最后一条if,那么我们就需要对最后一条再加上一个限定条件,有单词也就是说count !=0的时候才打印出count的值。程序修改为:

int main (void)
{ 
	char c;
	int count=0;
	scanf("%c",&c);
	while(c != '.'){
		if(c==' '){
			printf("%d ",count);
			count=0;
			}
		else{
			count++;
		}	
		scanf("%c",&c);
	}
	if(count!=0 && c=='.') printf("%d",count);
	return 0; 
}

再次提交空句子的测试点过了,但是连续多个空格和开头结尾多空格的错误依然在,继续修改代码支持这两个情况:

2)多个空格的情况:运行上述程序输入多个空格,结果如下,每个空格都会输出一个0,这显然不可以,那么怎么才能避免多个空格时,第一个空格输出值,有重复的空格时就不再输出,依然是首先分析打印0的语句是哪句?
单词长度试题的分析

分析下程序/调试一遍程序就知道while循环里的如果是空格则printf("%d ",count);,那么该printf语句就需要加上限定条件,如果有多个空格时就不要打印,但如果只有1个空格时可以打印,那么程序该怎么修改那?有多种办法,这里给出一个比较简介的方法,就是判断count是否为0,如果不为0则打印,否则不打印:

int main (void)
{ 
	char c;
	int count=0;
	scanf("%c",&c);
	while(c != '.'){
		if(c==' '){
			if(count !=0){
				printf("%d ",count);
			}
			count=0;
			}
		else{
			count++;
		}	
		scanf("%c",&c);
	}
	if(count!=0 && c=='.') printf("%d",count);
	return 0; 
}

再次提交到pta,多个空格的测试点过了。使用count是否等于0来解决多个空格的问题,大家认真体会下,也欢迎给我留言其他的办法。有的同学可能会说想不到这个办法,没关系,练多了就能想到了。
3)开头结尾多空格 这个测试点是格式错误,再审题,题目要求输出格式如下:

在一行中输出这行文本对应的单词的长度,每个长度之间以空格隔开,行末没有最后的空格。

根据这个要求,需要对打印格式进行调整,行末不能有空格,分析上述程序,当行尾有空格时,最后一个单词的长度是while循环里的printf打印的,是有空格的,那么对这个printf再加限定条件,如果是最后一个数值的打印则不加空格,否则加上空格,如何实现,方法也比较多,这里使用加标记flag的方法,,详情见下属代码,具体请自行分析:

int main (void)
{ 
	char c;
	int count=0;
	int flag=0;  //前面是否有单词标志
	scanf("%c",&c);
	while(c != '.'){
		if(c==' '){
			if(count !=0){
				if(flag==1)
					printf(" %d",count);    //前面有单词,且行尾有空格的输出格式。
				else{
					printf("%d",count);  //第一个单词,且不是只有一个单词时的输出格式
					flag=1;
				}
				
			}
			count=0;
			}
		else{
			count++;
		}	
		scanf("%c",&c);
	}
	if(count!=0 && c=='.')    //行尾没有空格
		if(flag==0)
			printf("%d",count);  //只有一个单词时的输出格式,且行尾没有空格的输出格式
		else{
			printf(" %d",count);  //有多个单词,且行尾没有空格的输出格式
			flag=1;
		}
			
	return 0; 
}

有些同学问我flag的含义,首先表扬这些同学对难题的执着,非常赞,然后flag的含义我已经在上面代码中加上了注释,自行查看,其实是针对不同输入相应输出格式的选择,所以在看上述代码时,一定要使用调试单步执行的功能! 然后输入不同样例,比如上面说的只有一个单词、多个单词、行尾有多个空格,行头有多个空格,单词中间有多个空格等情况的排列组合,单步执行去分析和理解不同输入时输出。那么为什么要有这么多种输出方式,题意要求~