剑指offer--面试题4

题目:替换字符串中的空格为“%20”。

说明:在浏览器的地址栏中输入某个网址,在解析过程中会看到类似“%20”的字样,这应该就是网络编程涉及的内容。。。

   该题总体来说比较简单(连我都能想到!),个人认为考查的是思维的敏捷。

1、先按照自己的思路编程如下:

//以下为开辟新的存储单元,并在新的存储上执行替换O(n)
#include "stdafx.h"
#include <iostream>

using namespace std;

/*int main(int argc, char* argv[])
{
    char String[] = "We are happy.";
    char* str = String;
    char result0[30];  // char result0[] = "\0"; (会导致程序崩溃!)
                       // 预先开辟结果的存储空间
    char* result = result0;
    char* SubtituteString = "%20";
    char* Subtemp = SubtituteString;
    while(*str != '\0')
    {
        if(' ' == *str)
        {
            while(*SubtituteString != '\0')
            {
                *result = *SubtituteString;
                SubtituteString++;
                result++;
            }
            str++;
            SubtituteString = Subtemp;
        }
        else
        {
            *result = *str;
            result++;
            str++;
        }

    }
    *result = '\0';
    cout<<result0<<endl;
    return 0;
}*/

//以下为本地替换O(n)

int main(int argc, char* argv[])
{
    char String[30] = "We are happy.";
    int len = strlen(String);
    int i = 0, num = 0;

    //找空格总数O(n)
    while(i < len)
        if(String[i++] == ' ')
            num++;
    //最终字符串所占空间
    int totallen = len+2*num;
    String[totallen] = '\0';
    //由后向前移动字符
    while(len)  //O(n)
    {
        if(String[len-1] != ' ')
            String[--totallen] = String[--len]; //一步到位
        else
        {

            String[--totallen] = '0';
            String[--totallen] = '2';
            String[--totallen] = '%';
            --len;
        }

    }  //减少移动次数
    cout<<String<<endl;
    return 0;
}

经过自己分析,无论本地替换还是开辟新的存储单元替换,时间复杂度都可以达到O(n).

看过作者的代码,自己写的代码无论从可读性、还是健壮性来说都存在差距!

1、变量命名上,尽量一眼看穿用途

2、无论指针还是数组名,因为都是地址,所以使用之前判空

3、当替换最后一个空格之后,两个指针会重合,此作为循环结束条件之一。

 

重写作者代码以加深印象:

//length为string字符数组的总容量

void ReplaceBlanks(char string[], int length)
{
    if(string == NULL || length <=0)
        return;
    //originalLength为string[]的实际长度
    int originalLength = 0;
    int numberOfblanks = 0;
    int i = 0;
    while(string[i] != '\0')
    {
        ++originalLength;
        if(string[i] == ' ')
            ++numberOfblanks;
        ++i;
    }
    //newLength为空格替换为"%20"后,字符串实际长度
    int newLength = originalLength + 2 * numberOfblanks;
    //判断newLength是否过界
    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--;

    }
}

 

相关题目:有序数组A1,A2,且A1空间充足,要求:将A1,A2合并到A1且最终结果有序。

int main()
{
    int Array1[20] = {1,2,13,19,22};
    int Array2[5] = {3,4,21,35,78};
    MergeSortedArray(Array1,Array2,5,5);
    return 0;
}

void MergeSortedArray(int Array1[], int Array2[], int size1,int size2)
{
    //数组由小到大排列
    //指针、大小判空
    if(Array1 == NULL || Array2 == NULL || size1 == 0 || size2 == 0)
        return;
    //
    int TotalLength = size1+size2;
    int OutputLength = TotalLength;
    TotalLength--;
    int IndexOfArray1 = size1-1;
    int IndexOfArray2 = size2-1;
    while(IndexOfArray1>=0 && IndexOfArray2>=0)
    {
        if(Array1[IndexOfArray1] > Array2[IndexOfArray2])
        {
            Array1[TotalLength--] = Array1[IndexOfArray1];
            IndexOfArray1--;
        }
        else
        {
            Array1[TotalLength--] = Array2[IndexOfArray2];
            IndexOfArray2--;
        }
    }
    //得到剩余数字的索引,分类讨论
    if(IndexOfArray1 > IndexOfArray2)
        while(IndexOfArray1 >= 0 && TotalLength >=0)
        {
            Array1[TotalLength--] = Array1[IndexOfArray1];
            IndexOfArray1--;
        }
    else
        while(IndexOfArray2 >= 0 &&TotalLength >=0)
        {
            Array1[TotalLength--] = Array2[IndexOfArray2];
            IndexOfArray2--;
        }
    //输出排序后整个数组
    for(int i=0; i<OutputLength; i++)
        cout<<Array1[i]<<',';
    cout<<endl;
}

PS:程序仍有不少瑕疵。。。,自己可提升的空间太大了!!!

posted on 2013-07-25 19:00  -赶鸭子上架-  阅读(344)  评论(0编辑  收藏  举报