C++积累04_单行英文语句的单词计数

再来积累一道题。

题目描述

统计一个英文句子中单词的个数,假定句子中只包含字母和空格,各单词之间用空格分隔,单词之间的空格可以有多个。

样例输入:i am student
样例输出:3

思路

要看一个英文句子中有几个单词,有两种方法。

  1. 看这个语句中有几个单词与单词之间的空档,假设有x个空档,那么单词个数就有(x+1)个。
    //注:空档不是空格,因为单词之间有多个空格。多个空格组成空档。
  2. 把这个句子以空档为间隔,分成多个字符串,看能分成几个子字符串。

解决方案1

第一种方法,使用类来解决。代码如下:

	//【这个程序的思路其实就是寻找存在于两个单词中间的空挡有多少个】
	string s1;

	getline(cin, s1, '\n');

	int countSpace = 0;//记录空格个数

	bool lead = (s1[0] != ' ');
	//这里去掉括号也是可以的,赋值时先计算右侧表达式的值,再赋给左侧变量
	//这里是看输入的字符串前面有没有空格,如果没有的话,lead为1

	for (unsigned int i = 0; i < s1.length(); i++)
		//这里是对每一个下标都进行判断,外层是遍历每一个下标
		//但是内层还有一个for循环,内层的是用来跳过多个相同的空格的

	{
		if (s1[i] == ' ')//如果某一个元素是空格,那么就要看它下面的元素是不是空格
		{
			for (; i < s1.length() && s1[i] == ' '; i++);
			//下标首先要小于字符串的总长度,并且当前这个索引对应的元素也得为空格
			//满足这两个条件,索引才自增。
			//下标循环到下一个非空格的字符
			
			countSpace += lead && (i != s1.length());
			//前面这个lead就是判断一下每一个句子的开头是不是含有空格
			//只起这一个作用,之后lead就一直是1了
			//【这个程序的思路其实就是寻找存在于两个单词中间的空挡有多少个】
			//所以如果lead==0,说明最开始的地方就有空格,那么这个时候是不能算在内的
			//当然,如果说经历了上面那个跳过空格的for循环后,索引i==s1.length(),
			//说明这个句子的最后全是一堆空格,这堆空格后面也没有单词了
			//所以必须要i!=s1.length(),或者这里写i<s1.length()也可以。
			//同时满足既不是开头的空格,也不是最末尾的空格的空挡,countSpace才计数

			lead = 1;
		}
	}
	
	cout << countSpace + 1 << endl;

这里补充一下中的getline():

cin有其缺陷,cin会忽略(传递并忽略)任何前导白色空格字符
例如空格、制表符、换行符
cin一接触到第一个非空格字符即开始阅读,当读取到下一个空白字符就停止读取

<string>中的getline()就能弥补这个不足。【注意是<string>里的!】

getline()的参数:getline(is,&str,delim)
is:		inputStream,输入流,例如cin
&str,	string类型的引用,用来储存输入流中的流信息
delim:	char类型的变量,设置的截断字符,缺省为遇到'\n'终止。

解决方案2

使用里的strtok函数:
(这个strtok在VS2019里显示不安全,比较麻烦,但是下程序在devc++中可行)

	char sentence[100];
	char* sSentence[100];
	
	gets(sentence);
	//gets()从输入流中读取字符串,
	//直至接受到换行符或EOF(End Of File,文字流的结尾,可以是标准输入或文件。)时停止,
	//并将读取的结果存放在参数所指向的字符数组中。换行符不作为读取串的内容,
	//读取的换行符被转换为‘\0’,由此来结束字符串。

	int count = 0;
	//用来计数

	sSentence[count++] = strtok(sentence, " ");
	//strtok首次使用需要指定sentence作为第一个参数,之后第一个参数为NULL。
	//具体见下面
	
	while (sSentence[count - 1] != NULL)//只要当前指针被定义了,就进行循环
	{
		sSentence[count++] = strtok(NULL, " ");//当前指针被赋值成为指向一个英语单词的指针
		//之后count++,移到下一个。
	}
	
	cout << count-1 << endl;

这里需要注意一下strtok()函数的用法:

strtok(str,delim)

当strtok()在str的字符串中发现参数delim,即“分割字符”时,则会将该字符改为\0 字符;
在第一次调用时,strtok()必需给予参数str,往后的调用则将参数str设置成NULL。每次调用成功则返回指向被分割出片段的指针
需要注意的是,使用该函数进行字符串分割时,会破坏被分解字符串的完整,调用前和调用后的串已经不一样了。
具体看这:https://www.cnblogs.com/zhoudingcocng/p/6554418.html

gets()函数用法见注释。

这些代码作为积累,以后再碰到类似的就能想起来了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值