输入一个字符串,字符串中可能包含多个连续的空格,请将多余的空格去掉,只留下一个空格。
输入格式
共一行,包含一个字符串。
输出格式
输出去掉多余空格后的字符串,占一行。
数据范围
输入字符串的长度不超过 200。
保证输入字符串的开头和结尾没有空格。
输入样例:
Hello world.This is c language.
输出样例:
Hello world.This is c language.
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main()
{
string s;//这个是原字符串,就是你要输入的字符串
getline(cin, s);//输入一整行字符串,包括空格在内也读入
string r;/*这是定义的第二个字符串,叫答案字符串,就是经过一系列操作后,
得到的结果
*/
for (int i = 0; i < s.size(); i++)//这个循环是遍历,没什么好说的
if (s[i] != ' ')
r += s[i];
/*在遍历的过程中,那一位上如果没有空格,有字符的话,那么就r+=s[i];
成为结果的一部分
*/
else/*这是反过来,要是在遍历的过程中遍历到了空格,那么就要把遍历到的所有空格删掉,
但是因为题目要求,最后输出的时候要有一个空格间隔,所以多一步操作
*/
{
r += ' ';/*这里是让最后的结果之间有空格,你想想,要是没这一步,那么就会将遍历到的
不是空格的字符接连输出,到那时就凑成一团了,就不符合最后输出的要求
*/
int j = i;
/*
当i遍历到了空格后,就开始着手准备删除空格了,这个时候定义一个变量j,也用遍历的方法来跑,
只不过这次是遍历空格,条件与之前的if语句恰好相反,遍历,要是遍历到空格那就继续遍历,
j++,直到遍历到不是空格为止,那么此时,就又轮到i了,i又遍历字符,又到空格停止,
就这样来回往复,直到最后输出答案
*/
while (j < s.size() && s[j] == ' ')
j++;
i = j - 1;/*因为每回合循坏i都要++,所以i+1的位置就是j的,即i=j-1;
*/
}
cout << r << endl;//这里直接输出字符串r就行,因为上面的操作已经得到了结果,这里只需要输出就行
return 0;
}
这个题的思想就是利用双指针来写的,是先读入所有的字符,包括空格,再利用遍历的
方法来清掉空格,最后得到结果,而且有两个字符串的表示,一个是刚输入的,还未操作过的,
另一个是结果,是已经操作完,得到的正确结果,也用字符串表示,这是我觉得巧妙的地方,也拓宽了我的思路。
这是我自己做的时候画的草稿图,画的不好还请见谅。
除了这种以外,还有一种思路做这题,那就是让他不完整输入,让其输出的时候自己过滤掉空格,那这就是语言运用的细节,我觉得也有必要再思考,这第二种方法如下:
cin做法
#include <iostream>
using namespace std;
int main()
{
string s;
while (cin >> s) cout << s << ' ' ;
/*因为cin读入时要是读到了空格,它会自动终止,从而导致读不了空格后面的字符串,
所以利用这个特性,来实现清除字符串中空格的目的。
这里用的是while这个循环,它的意思是只要是输入字符串,循环里面的语句都能运行,这有点
死循环的感觉,但是对于这道题是十分好用的,因为我们需要不断的输入,即使是cin读到了
空格终止了,我们也要让其继续输入,还是那样,cin读到字符串就一直读入,到空格就不读,到后面
字符串又读,不过要在循环语句内,毕竟要多次读入,所以这个while循环既简洁又实用,当输出的时候
,已经过滤完了空格,所以直接cout<<s,直接输出,因为输出也是一行,所以就不要endl,就不用换行了,
因为题目要我们输出之间有空格,所以在后面加一个空格即可
*/
return 0;
}
由此看出,语句的用法细节也要掌握,这样在某些时候就会有大用。