4. 替换空格

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

  思路

  1.先计算新数组总的长度,由于空格换成"%20",所以每个空格会额外多出两个字符。所以新的长度 = 原来长度 + 空格数 * 2。
  2.准备两个指针P1, P2。P1指向原始字符串的末尾,P2指向新字符串的末尾。
  3.接下来向前移动指针P1,逐个把它指向的字符复制到P2指向的位置,直到碰到了第一个空格为止。碰到第一个空格后,把P1向前移动1格,在P2之前插入字符串"%20"。由于"%20"的长度为3,同时也需要把P2向前移动3格。
  4.反复操作3步骤,当P1和P2指向同一个位置时,表明所有空格都已经替换完毕。所有的字符都只复制(移动)一次,所以时间复杂度为O(n)。

  测试用例
  
  1.输入的字符串中包含空格(空格位于字符串的最前面,最后面,以及中间,以及有连续多个空格)
  2.输入的字符串中没有空格。
  3.特殊输入测试(字符串是个NULL指针、字符串是个空字符串、字符串只有一个空格字符、字符串中只有连续多个空格)。

  代码

#include<iostream>
#include<cstring>
using namespace std;

//length 为字符数组 string的总容量
void ReplaceBlank(char string[], int length)
{
    if (string == NULL || length <= 0)
    {
        return;
    }

    //originalLength为字符串string的实际长度
    int originalLength = 0;
    int numberOfBlank = 0;
    int i = 0;
    while(string[i] != '\0')
    {
        ++originalLength;

        if (string[i] == ' ')
        {
            ++numberOfBlank;
        }

        ++i;
    }

    //newLength为替换空格之后新的长度
    int newLength = originalLength + numberOfBlank * 2;
    if (newLength > length)
    {
        return;
    }

    int indexOfOriginal = originalLength;  //指针P1
    int indexOfNew = newLength;            //指针P2
    while (indexOfOriginal >= 0 && indexOfNew > indexOfOriginal)
    {
        if (string[indexOfOriginal] == ' ')
        {
            string[indexOfNew--] = '0';
            string[indexOfNew--] = '2';
            string[indexOfNew--] = '%';
        }
        else
        {
            string[indexOfNew--] = string[indexOfOriginal];
        }

        --indexOfOriginal;
    }

}

void Test(char str[], int length, char expected[])
{
    ReplaceBlank(str, length);

    if(expected == NULL && str == NULL)
        cout << "passed" << endl;
    else if(expected == NULL && str != NULL)
        cout << "failed" << endl;
    else if(strcmp(str, expected) == 0)
        cout << "passed" << endl;
    else
        cout << "failed" << endl;
}


void Test1()
{
    const int length = 100;

    char str[length] = "hello world";
    Test(str, length, "hello%20world");
}

void Test2()
{
    const int length = 100;

    char str[length] = "helloworld";
    Test(str, length, "helloworld");
}

//空指针
void Test3()
{
    Test(NULL, 0, NULL);
}

//空字符串
void Test4()
{
    const int length = 100;

    char str[length] = "";
    Test(str, length, "");
}

int main()
{
    Test1();
    Test2();
    Test3();
    Test4();

    return 0;
}

相关题目:

  有两个排序的数组A1 和 A2,内存在A1的末尾有足够多的剩余空间容纳A2。请实现一个函数,把A2中的所有数字插入到A1中并且所有的数字是排序的。

方法:从尾刀头比较A1 和 A2中的数字,并把较大的数字复制到A1的合适位置。

举一反三:

合并两个数组(包括字符串)时,如果从前往后复制每个数字(或字符)需要重复移动多次,那么我们可以考虑从后往前复制,这样就能减少移动的次数,从而提高效率。

猜你喜欢

转载自my.oschina.net/134596/blog/1787864
今日推荐