zoukankan      html  css  js  c++  java
  • 剑指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[] = ""; (会导致程序崩溃!)
                           // 预先开辟结果的存储空间
        char* result = result0;
        char* SubtituteString = "%20";
        char* Subtemp = SubtituteString;
        while(*str != '')
        {
            if(' ' == *str)
            {
                while(*SubtituteString != '')
                {
                    *result = *SubtituteString;
                    SubtituteString++;
                    result++;
                }
                str++;
                SubtituteString = Subtemp;
            }
            else
            {
                *result = *str;
                result++;
                str++;
            }
    
        }
        *result = '';
        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] = '';
        //由后向前移动字符
        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] != '')
        {
            ++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:程序仍有不少瑕疵。。。,自己可提升的空间太大了!!!

    清醒时做事,糊涂时读书,大怒时睡觉,独处时思考; 做一个幸福的人,读书,旅行,努力工作,关心身体和心情,成为最好的自己 -- 共勉
  • 相关阅读:
    js 自定义属性
    js innerText、textContent、innerHTML的区别和各自用法
    js 的常用选择器
    js Array属性和用法
    js---String对象
    iframe自适应高度js
    thinkphp 的save()不能更新数据解决办法
    转义字符
    获取客户端真实ip
    thinkphp条件查询和模糊查询的一些方法
  • 原文地址:https://www.cnblogs.com/hello-yz/p/3215088.html
Copyright © 2011-2022 走看看