面试题4:替换空格和清除空格

1.替换空格

题目:请实现一个函数,把字符串中的每个空格替换成“%20”。例如输入“We are happy.”,则输出“We%20are%20happy.”。

1.1分析

将长度为1的空格替换为长度为3的“%20”,字符差的产度变长。如果允许我们开辟一个新的数组来存放替换空格后的字符串,那么这道题目就非常简单。设置两个指针分别指向新旧字符串首元素,遍历原字符串,如果碰到空格就在新字符串上填入“%20”,否则就复制元字符串上的内容。但是如果面试官要求在原先的字符串上操作,并且保证原字符串有足够长的空间来存放替换后的字符串,那么我们就得另想方法。

如果从前往后替换字符串,那么保存在空格后面的字符串肯定会被覆盖,那么我们就考虑从后往前进行替换。

  1. 首先遍历原字符串,找出字符串的长度以及其中的空格数量,
  2. 根据原字符串的长度和空格的数量我们可以求出最后新字符串的长度。
  3. 设置两个指针originalIndex和newIndex分别指向原字符串和新字符串的末尾位置。
  4. 如果originalIndex指向内容不为空格,那么将内容赋值给newIndex指向的位置,如果originalIndex指向为空格,那么从newIndex开始赋值“02%”
  5. 直到originalIndex==newIndex时表明字符串中的所有空格都已经替换完毕。

1.2代码实例

View Code
#include<iostream>
#include<stdlib.h>
using namespace std;

void ReplaceBlank(char string[],int len)
{
    if(string==NULL||len<=0)
        return;

    int stringlen=0;
    int blanknum=0;
    int i=0;
    //求字符串长度和空格数量
    while(string[i]!='\0')
    {
        ++stringlen;
        if(string[i]==' ')
            ++blanknum;
        ++i;
    }

    int newlength=stringlen+blanknum*2;//求新字符串长度
    if(newlength>len)
        return;
    //设置两个指针指向新旧数组末尾
    int originalIndex=stringlen;
    int newIndex=newlength;

    //当上面两个指针指向同一个元素则表明没有空格
    while(originalIndex>=0&&newIndex>originalIndex)
    {
        if(string[originalIndex]==' ')
        {
            string[newIndex--]='0';
            string[newIndex--]='2';
            string[newIndex--]='%';
        }

        else
        {
            string[newIndex--]=string[originalIndex];
        }
        --originalIndex;
    }
}

void main()
{
    char test[100]="we are happy.";
    cout<<test<<endl;//we are happy.

    ReplaceBlank(test,100);
    cout<<test<<endl;//we are happy.

    system("pause");
}

2.清除空格

题目:请实现一个函数,把字符串中的每个空格清除掉。例如输入“We are happy.”,则输出“Wearehappy.”。

2.1分析

这道题目是需要清楚空格,那么清除空格后所得到的字符串要比原先的字符串要短,这是我们从头到尾进行清楚空格的话就不会覆盖到空格后面的字符,所以我们可以从头开始清除。

  1. 设定两个指针p1和p2初始状态都指向字符串首字符。
  2. 如果p2指向的元素不为空格,那么将p2指向的内容赋值给p1,然后p1和p2指向下一个元素;如果p2指向的内容为空格,那么p2指向下一个元素。
  3. 直到p2指向字符串末尾的'\0'时清除空格结束。

2.2代码实例

View Code
#include<iostream>
#include<stdlib.h>
using namespace std;

void ReplaceBlank(char *s)
{
    //设置两个指针指向数组首元素
    char *p1=s;
    char *p2=s;

    while('\0'!=*p1)
    {
        if(' '!=*p2)//如果p2指向不为空格,则将p2指向内容复制给p1指向
            *p1++=*p2++;
        else//如果p2指向为空格,则p2指针向前移动一格。
            p2++;
    }
}

void main()
{
    char test[100]="we are happy.";
    cout<<test<<endl;//we are happy.

    ReplaceBlank(test);
    cout<<test<<endl;//we are happy.

    system("pause");
}

 3.清楚多余空格

题目:给定字符串,删除开始和结尾处的空格,并将中间的多个连续的空格合并成一个。例如输入"  We   are   happy.   ",则输出"We are happy."

 3.1分析

这道题目跟第二题类似,都是需要删除空格,这样可以肯定输出的字符串长度小于等于原先字符串的长度,那么就可以从头往后遍历而不怕后面的字符被覆盖。因为需要删除开始和结尾处处的空格,而字符串中间的空格又需要保存一个,我们需要进行另外的处理。我们可以通过设置一个标识位来进行处理,定义一个bool变量keep_space表示是否保存一个空格,如果keep_space=true表示保存一个空格,如果keep_space=false则不保存空格。初始化的时候将keep_space设为false,这样开始阶段的空格都不会被保存,当碰到一个不为空格的字符是,保存该字符,然后设置keep_space=true表明会保存字符串中的第一个空格,这样在碰到第一个个空格时就能够保存。

在字符串结果,经过上述几步操作,可以保证字符串结尾要么是非空字符,要门是一个空字符,这样进行一次判断就好了,如果是空格字符,这将该空格设为'\0',如果不为空字符,则在其后面加上'\0'

3.2代码实例

View Code
#include<iostream>
#include<stdlib.h>
using namespace std;

void ReplaceBlank(char *str)
{
    int index=0;
    bool keep_space=false;//表示是否允许保存空格,初始为false用于去除字符串刚开始的多余空格
    for(int i=0;str[i]!='\0';i++)
    {

        if(str[i]!=' ')//如果便利到的是非空格字符,则进行赋值
        {
            str[index++]=str[i];
            keep_space=true;//表示允许保存一个空格
        }

        else if(keep_space)//如果允许有一个空格
        {
            str[index++]=str[i];
            keep_space=false;
        }
    }

    //处理字符串最后的多余空格,经过上述处理,字符串最多是在index-1位置多出一个空格。
    if(index>0&&str[index-1]==' ')
    {
        str[index-1]='\0';
    }
    else
    {
        str[index]='\0';
    }
}

void main()
{
    char test[]=" we  are  happy. ";
    cout<<strlen(test)<<endl;
    cout<<sizeof(test)<<endl;
    cout<<test<<endl;//we are happy.
    ReplaceBlank(test);
    cout<<test;//we are happy.
    system("pause");
}
原文地址:https://www.cnblogs.com/xwdreamer/p/2490033.html