替换空格(面试题4)

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

第一种方法:
每遇到一个空格,让数组之后的元素都往后移。

void replaceSpace(char string[]){
    cout << "before: " << string << endl;

    if(string == NULL || strlen(string) <= 0)
        return;

    int len = strlen(string);
    int k = 0;
    for(int i = 0; i < len; i++){

        if(string[i] == ' '){
            k++;
            for(int j = len + k*2 - 1; j > i; j--){

                string[j] = string[j-2];
            }

            string[i] = '%';
            string[i+1] = '2';
            string[i+2] = '0';

        }else{
            continue;
        }
    }

    string[len+k*2] = '\0';
    cout << "after: " << string << endl;
}

很明显这个方法的效率是不高的,时间复杂度是O(n2).

方法二:先遍历一次字符串,统计出字符串中空格的总数,并计算出替换之后字符串的总长度。每替换一个空格,长度增加2,因此替换以后字符串的长度等于原来的长度加上2乘以空格数目。
代码如下:

/*length为字数组string的所能容乃的最大容量*/
void replaceSpace2(char string[], int length){

    int originalLength = 0;

    if(string == NULL || length <= 0){
        return;
    }

    int numberOfBlank = 0; 

    int i = 0;
    while(string[i] != '\0'){
        ++originalLength;//strlen(string)是一样的

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

        i++;
    }

    int newLength = originalLength + numberOfBlank*2;

    if(newLength > length)
        return;

    int indexOfOriginal = originalLength;
    int indexOfNew = newLength;

    while( indexOfOriginal >= 0 && indexOfNew > indexOfOriginal){
        if(string[indexOfOriginal] == ' '){
            string[indexOfNew--] = '0';
            string[indexOfNew--] = '2';
            string[indexOfNew--] = '%';
        }else{
            string[indexOfNew--] = string[indexOfOriginal];
        }

        --indexOfOriginal;
    }

    cout << string << endl;

}

这是从字符串的后面开始复制和替换。这里准备了两个指针,P1和P2。P1指向原始字符串的末尾,P2指向替换之后的字符串末尾。接下来向前移动指针P1,逐个把它指向的字符复制到P2指向的位置,知道碰到第一个空格为止。碰到空格之后,把 P1向前移动1格,在P2前插入字符串“%20”。

在另外用string写一个函数:

string replaceSpace(string iniString, int length) {

        for(int i = 0; i < length;){
            int spaceIndex = iniString.find(" ", i);

            if(spaceIndex == -1)
                break;

            iniString.replace(spaceIndex, 1, "");

            iniString.insert(spaceIndex,"%20");

            i = spaceIndex+1;
            length += 2;
        }

        return iniString;
    }

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

我这里用的是整型数组,没有使用泛型编程。如果有需要的话,自己好好琢磨。代码如下:

/************************************************************************/
/*lenA、lenB分别是a、b数组的长度 
 *length为数组a所能容纳的最大容量 
 *两个数组升序排序                                      */
/************************************************************************/
void sortArrayCat(int a[], int b[], int lenA, int lenB, int length){

    if(a == NULL || b == NULL){
        return;
    } 

    if(lenA <= 0 ||  lenB<= 0 || (lenA + lenB) > length){
        return;
    }

    int newLength = lenA + lenB;

    int indexOfOriginalA = lenA-1;
    int indexOfOriginalB = lenB-1;
    int indexOfNew = newLength-1;

    /*将数组b插入到数组a中*/
    while(indexOfOriginalB >= 0 && indexOfOriginalA >= 0){
        if(b[indexOfOriginalB] > a[indexOfOriginalA]){
            a[indexOfNew--] = b[indexOfOriginalB--];

        }else{
            a[indexOfNew--] = a[indexOfOriginalA--];
        }

        /*if(indexOfOriginalB < 0 && indexOfOriginalA >  indexOfOriginalB){
            a[indexOfNew--] = a[indexOfOriginalA--];
        }

        if(indexOfOriginalA < 0 && indexOfOriginalA <= indexOfOriginalB){
            a[indexOfNew--] = b[indexOfOriginalB--];*/
        }
    }

    if (indexOfOriginalA == 0)
    {   
        while (indexOfOriginalB >= 0)
        {
            a[indexOfNew--] = b[indexOfOriginalB--];
        }
    }

    if(indexOfOriginalB == 0){
        while (indexOfOriginalA >= 0)
        {
            a[indexOfNew--] = a[indexOfOriginalA--];
        }

    }

    for(int i = 0; i < newLength; i++)
        cout << a[i] << " ";

    cout << endl;
}

第一个while循环里注释掉的代码是优化代码,可以代码后面的两个循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值