《剑指offer》第2.3节 数据结构三

2.3.2 字符串

  • C++ 中每个字符串都以 '\0' 结尾,即每个字符串都有一个额外字符开销,注意字符串越界问题。一个char:1B。
  • 一维数组和指针的直接区别:

直接用数组名进行比较,比较的是整个字符串的地址,因为是不同变量所以存储位置不同。

用指向字符串的指针进行比较,因为指向的是同一个常量,所以直接用指针比较就是比较指针的内容,地址是相同的。

#include <iostream>

using namespace std;

int main()
{
    char str1[] = "hello";
    char str2[] = "hello";
    if(str1 == str2)
    {
        cout<<"str1 is same as str2"<<endl;
    }
    else
    {
        cout<<"str1 and str2 isn't same"<<endl;
        cout<<str1<<" : "<<str2;
    }

    char* str3 = "hello world";
    char* str4 = "hello world";
    if(str3 == str4)
    {
        cout<<"str3 is same as str4"<<endl;
        cout<<str3<<" : "<<str4;
    }
    else
    {
        cout<<"str3 and str4 isn't same"<<endl;
        cout<<str3<<" : "<<str4;
    }

    return 0;
}

输出结果:

str1 and str2 isn't same
0x6dfef2 : 0x6dfeec
str3 is same as str4
h : h

值得注意的是:cout 输出的类型是本来变量被定义的类型,比如char[],就输出这个字符串;而在输出指针时,输出的是指针指向内存区域中的内容。

面试题4:替换空格

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

分析:在网络编程中,如果URL参数中含有特殊字符,如空格、'#'等,可能导致服务器端无法获得正确的参数值。我们需要将这些特殊符号转换成服务器可以识别的字符。转换规则是 在 '%'后面跟上ASCII码的两位十六进制的表示。比如空格的ASCII码是32,即十六进制的0x20,因此空格被替换成 "%20"。再比如,'#'的ASCII码为35,即十六进制的0x23,它在URL中被替换为"%23"。

法一:时间复杂度为O(n^2):假设字符串的长度为n。对于每个空格字符,需要移动后面O(n)个字符,因此对含有O(n)个空格字符的字符串而言总的时间效率为O(n^2)。

#include <iostream>

using namespace std;

char* replace(char* str1,const int num,int i)
{
//    static char str2[num];        //static 定义的数组中索引值一定是一个常数,不能是符号,即使定义为const 的常量也不行
    char* str2 = new char [num];

    int j;
    for(j = 0;j < i;j++)
    {
        str2[j] = str1[j];
    }
    str2[j] = '%';
    str2[++j] = '2';
    str2[++j] = '3';
    for(i++,j++;j < num;j++,i++)
    {
        str2[j] = str1[i];
    }
    return str2;
}

int main()
{
    /*定义一个字符串,之后改为输入一个字符串*/
    char* str1 = "Hello world !";
    int num = 0,i = 0;          //num为字符串不包含'\0'的长度,'\0'==NULL?
    while(str1[i] != NULL)
    {
        i++;
        num++;
    }

    /*找到替换位置i,并调用函数进行替换*/
    i = 0;
    while(i != num)
    {
        if(str1[i] == ' ')
        {
            num+=4;                         //除增加的3个字符外,还需要增加'\0'字符串的结束标志
            str1 = replace(str1,num,i);
            i+=3;
        }
        i++;
    }

    cout<<str1<<endl;
    delete<<str1;

    return 0;
}

法二:我们一边查找一边复制,所以时间复杂度降为O(n)。

#include <iostream>

using namespace std;

char* replace(char* str1,int num,int i)
{
    int num_str2 = num + 1 + i * 2;
    char* str2 = new char [num_str2];
    str2[num_str2--] = '\0';        //str2[17]是num_str2的最后一个位置'\0'
    char* p1 = &str1[0];

    for(int j1 = num;j1 >= 0;j1--)
    {
        if(p1[j1] == ' ')
        {
             str2[num_str2] = '3';
             num_str2--;
             str2[num_str2] = '2';
             num_str2--;
             str2[num_str2] = '%';
             num_str2--;
        }
        else
        {
            str2[num_str2] = p1[j1];
            num_str2--;
            num--;
        }
    }
    return str2;
}

int main()
{
    char* str1 = "Hello world !";
    int i = 0,num = 0;

    while(str1[num] != NULL)
    {
        if(str1[num] == ' ')
        {
            i++;
        }
        num++;
    }

    str1 = replace(str1,num,i);

    cout<<str1;

    return 0;
}

不过还是有两个问题:

第一个就是如何输入一个不定长度的数组。

第二个问题就是: 为什么不能将:str2[num_str2] = '3'; num_str2--; 替换为 str2[num_str2 --]?编译的结果就发生了问题,原因在哪?难道运算优先级不对?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值