1.清除空格
编写一个程序,把字符串中的每个空格清除掉。例如输入“We are happy.”,则输出“Wearehappy.”。
- 编程思路
由于字符串的内存分配方式是连续分配的。我们从字符串当中删除一个空格字符时,需要把后面所有的字符往前移动一个字节的位置。但如果每次删除都需要移动字符串后面的字符的话,对于一个长度为n 的字符串而言,删除一个空格字符的时间复杂度为O(n) 。而对于本题而言,有可能要删除的空格字符的个数是n ,因此该方法就删除而言的时间复杂度为O(n2) 。
事实上,我们并不需要在每次删除一个空格的时候都去移动后面所有的字符。我们可以设想,当一个空格需要被删除的时候,我们把它所占的位置让它后面的字符来填补,也就相当于这个空格被删除了。具体方法为:
(1)定义两个指针p1和p2,p2用于遍历原始字符串,p1用于指向结果字符串中当前赋予的非空格字符。初始状态都指向字符串首字符。
(2)如果p2指向的元素不为空格,那么将p2指向的内容赋值给p1,然后p1和p2指向下一个元素;如果p2指向的内容为空格,那么p2指向下一个元素,p1保持不动。
(3)直到p2指向字符串末尾的“\0”时,清除空格结束。
- 源程序及运行结果
#include<iostream>
using namespace std;
int main()
{
char str[81];
cin.getline(str,80,'\n');
//设置两个指针指向数组首元素
char *p1=str;
char *p2=str;
while(*p1!='\0')
{
if(*p2!=' ') //如果p2指向不为空格,则将p2指向内容复制给p1指向
*p1++=*p2++;
else //如果p2指向为空格,则p2指针向前移动一格。
p2++;
}
cout<<str<<endl;
return 0;
}
上例删除字符串中的所有空格,在实际应用中,有时空格需部分保留,如字符串中的多个连续空格,则保留1个。这样,可以将这个问题进行扩展,对给定字符串,删除开始和结尾处的空格,并将中间的多个连续的空格合并成一个。
2.清除多余空格
编写一个程序,对给定的字符串,删除开始和结尾处的空格,并将中间的多个连续的空格合并成一个。例如输入" We are happy. ",则输出"We are happy."
- 编程思路
因为需要删除开始和结尾处的空格,而字符串中间的空格又需要保存一个,因此需要进行另外的处理。可以通过设置一个标识位来进行处理,定义一个bool变量flag表示是否保存一个空格,如果flage=true表示保存一个空格,如果flag=false则不保存空格。初始化的时候将flag设为false,这样开始阶段的空格都不会被保存,当碰到一个不为空格的字符时,保存该字符,然后设置flag=true表明会保存后面待扫描的字符串中的第一个空格,这样在碰到第一个空格时就能够保存。
按上面的操作方法,扫描结束后,目标字符串的结尾要么是非空格字符,要么是一个空格字符,这样进行一次判断就好了,如果是空格字符,这将该空格设为“\0”,如果不为空格字符,则在其后面加上“\0”。
- 源程序及运行结果
#include<iostream>
using namespace std;
int main()
{
char str[81];
cin.getline(str,80,'\n');
int index=0;
bool flag=false;
for(int i=0;str[i]!='\0';i++)
{
if(str[i]!=' ') // 如果遍历到的是非空格字符,则进行赋值
{
str[index++]=str[i];
flag=true; // 表示允许保存一个空格
}
else if(flag) // 如果允许有一个空格
{
str[index++]=str[i]