来自 剑指offer 名企面试官精讲典型编程题
数组可以说是最简单的一种数据结构,他占据着连续的一块内存并按照顺序存储数据。
数组的空间效率不是很好,经常会有空闲的区域没有得到充分的利用。
根据数组时间效率高的优点,用数组来实现简单的哈希表:用数组的下标设为哈希表的键值,而把数组中的每一个数字设为哈希表的值,这样每一个下标及数组中该下标对应的数字就组成了一个键值-值得配对。有了这样的哈希表就可以再O(1)实现查找。
同时C++的STL中的vector是另一种动态数组。需要了解。
C++中数组与指针的区别
运行下面的代码,请问输出时什么?
#include <iostream>
using namespace std;
int GetSize(int data[])
{
return sizeof(data);
}
int main()
{
int data1[] = {1,2,3,4,5};
int size1 = sizeof(data1);
int* data2 = data1;
int size2 = sizeof(data2);
int size3 = GetSize(data1);
cout << size1 << size2 << size3 <<endl;
return 0;
}
答案是20 ,4 ,4 。
sizeof是求数组的大小。这个数组包含5个整数,每个占4字节,因此总共是20字节。
data2声明为指针,尽管它指向数组的第一个数字,但他的本质仍然是一个指针。而32位机器整整占4个字节
在C、C++中,当数组作为函数的参数进行传递时,数组就自动退化为同类型的指针。所以结果也为4.
2. 二维数组中的查找:
题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
3. 字符串:
当几个指针赋值给相同的常量字符串时,他们实际上会指向相同的内存地址。
但用常量内存初始化数组时,情况就有所不同:
运行下面代码, 结果是:notequal equal
int main(int argc,char* argv[])
{
char str1[] = "hello world";
char str2[] = "hello world";
char* str3 = "hello world";
char* str4 = "hello world";
if(str1 == str2)
cout << "equal" << endl;
else
cout << "not equal" << endl;
if(str3 == str4)
cout << "equal" << endl;
else
cout << "not equal" << endl;
return 0;
}
我们会分配2个长度为12字节的空间给str1,str2 并把“hello word”的内容复制到数组中去。
这是2个初始地址不同的数组,所以str1与str2的值不同。
在C#中,封装字符串的类型System.String有一个非常特殊的性质:String的内容是不能改变的。一旦试图改变String的内容,就会产生一个新的实例。
String str = "hello";
str.ToUpper();
str.Insert(0,"WORLD");
虽然对str做了ToUpper和Insert操作,但操作的结果都是生成一个新的String实例返回,str本身的内容不会改变(hello)。
用String作连续多次修改,每次都会产生一个临时对象,这样开销太大会影响效率。此时用StringBuilder更好。它能够容纳修改后的结果。
4. 替换空格
题目:请实现一个函数,把字符串中的每个空格替换成“%20”。例如输入“We are happy。“则输出”We%20are%20happy。“。
在网络编程中,如果URL参数中含有特殊字符,如空格 '#'等,可能导致服务器端无法获得正确的参数值。我们需要将这些特殊符号转换为服务器可以识别的字符。转换的规划是在%后面跟上ASCII码的2为16进制的表示。如空格的ASCII码为32,即16进制的0x20,因此空格被替换为%20.