替换空格题目

1、题目描述

请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

2、代码

1、自己原始的答案:

void replaceSpace(char *str,int length) 
    {
        vector<char> vec_char;
        for(int i=0;i<length;i++)
        {
            if(str[i] == ' ')
            {
                vec_char.push_back('%');
                vec_char.push_back('2');
                vec_char.push_back('0');
            }
            else
                vec_char.push_back(str[i]);
        }

        //char* cRes = new char[vec_char.size()];
        int i=0;
        for(auto iter = vec_char.cbegin();iter!=vec_char.cend();iter++)
        {
            str[i] = *iter;
            i++;
        }
        str[i] = '\0';
        //str = cRes;
    }//

问题: 从前向后复制,时间复杂度是O(N*N),时间复杂度过大,同时还应用了vector这个容器的,因此程序的执行时间也比较长。

2、之后的答案

void replaceSpace(char *str,int length) 
{
    if(str==NULL || length <= 0)
        return;

    int num1=0;
    char* p = str;
    while(*p!='\0')
    {
        if(*p == ' ')
            num1++;
        p++;
    }
    // 需要注意的是:这里加的是2,不是3,很容易出错
    str[num1*2+length]='\0';
    char* p1 = str + num1*2+length-1;
    p = str + length - 1;

    // 当P和p1所指向的地址相同的时候,一定是所有的空格全部插完了。
    while(p1!=p)
    {
        if(*p != ' ')
            *p1 = *p;
        else
        {
            *p1 = '0';
            *(--p1) = '2';
            *(--p1) = '%';
        }
        p1--;
        p--;
    }
}

时间复杂度是O(N)。

3、思路分析

1、主要的思路是:先计算好空格的数目,根据这个计算插入后需要的整个字符串的长度,从后向前进行插入和复制。这样就可以达到O(N)的复杂度。
2、插入的时候,先计算好需要的长度。一定要从后向前插入。

4、编程注意

1、之前的空格也是占一个字节的,因此如果有N个空格,那么最后在之前的字符串长度上需要增长的长度为 2*N,注意这里不是 3*N,这里很很容易犯错。不然两个指针一直没法相等,一直插不完,就会出错。
2、两个指针分别指向原始字符串的结尾的地址和计算好新字符串的结尾的字符的地址,当还有M空格的时候,两个指针的之间距离是2*M的距离,只有当所有的空格全部被插完之后,两个指针的值才会相同,这是插入就结束了。

—————————-分割线1————————

自己写了的一个测试函数

1、低级错误

int main()
{
    char* str = new char[100];
    str = "we are happy";
    replaceSpace(str,12);
    cout << str << endl;
    cin.get();
    return 1;
}

发现怎么运行都有错误,这里记录下自己犯的一个很低级的错误。”we are happy”是一个字符串常量,因此其是有一个char的地址的,开始定义的str指针的时候是令其指向了一段开辟内存的首地址,但是str = “we are happy”,使str的所指向内存的大小变化了,这时str后的内存大小是13(注意后面还有一个‘\0’字符),因此在插入函数通过该指针继续访问13个字节后面的内存就出错了。

2、正确

int main()
{
    char* str = new char[100];
    char* temp = "we are happy";
    for(int i=0;i<12;i++)
        str[i]=temp[i];
    replaceSpace(str,12);
    cout << str << endl;
    cin.get();
    return 1;
}

将字符串常量的每个字节的字符分别复制给str所指向的内存即可。

—————————-分割线2————————

举一反三

1 题目:合并两个都已经排好序的数组A1和A2,假设A1后面有足够的内存存放A2的数据。
2 基本思路:从后向前比较和插入
3**代码**

#include<iostream>
using namespace std;

void SortTwoArray(int* A, int* B, int sizeA, int sizeB)
{
    int* pA = A+sizeA-1;
    int* pB = B+sizeB-1;
    int* p = A + (sizeA+sizeB-1);
    while(p!=pA)
    {
        if(*pA > *pB)
        {
            *p = *pA;
            pA--;
        }
        else
        {
            *p = *pB;
            pB--;
        }
        p--;
    }
}


int main()
{
    int *A = new int[100];
    memset(A, -1,sizeof(int)*100);
    int *B = new int[10];
    for(int i=0;i<10;i++)
    {
        A[i] = i;
        B[i] = 2 * i - 5;
    }
    SortTwoArray(A, B, 10, 10);

    for(int i=0;i<20;i++)
        cout << A[i] << endl;
    system("pause");
    return 1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值