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 --]?编译的结果就发生了问题,原因在哪?难道运算优先级不对?