《程序员面试宝典第四版》笔记4

时间:2022-11-21 15:04:47
面试例题9:下列程序会在哪一行崩溃?
#include<iostream>
using namespace std;
struct S
{
int i;
int *p;
};
int main()
{


S s;
int *p=&s.i;
p[0]=4;
p[1]=3;
s.p=p;
s.p[1]=1;
s.p[0]=2;
}
解析:
int *p=&s.i;相当于int *p; p=&si;。 当执行p[0]=4; p[1]=3;的时候,p始终等于&si。s.p=p相当于建立了如下关系:
s.p存了p的值,也就是&s.i;s.p[1]相当于*(&s.i+1),即s.i的地址加1,也就是s.p。
s.p[1]跟s.p其实是同一个地方,所以到s.p[1]=1,那么s.p[0]将指向内存地址为1的地

方。s.p[0]=2;并不是给s.i赋值,而是相当于*((int *)1)=2;。也就是要访问0x00000001空间——对于一个未做声明的地址直接进行访问,所以访问出错。

#include<iostream>
using namespace std;
struct S
{
int i;
int *p;
};
int main()
{

S s;
int *p=&s.i;
p[0]=1;
p[1]=5;
cout<<p[0]<<" "<<s.i<<endl;
cout<<&p[0]<<" "<<&s.i<<endl;
cout<<p[1]<<" "<<s.p<<endl;

cout<<&p[1]<<" "<<&s.p<<" "<<&s.p[1]<<endl;
s.p=p;
cout<<p[0]<<" "<<s.i<<endl;
cout<<&p[0]<<" "<<&s.i<<endl;
cout<<p[1]<<" "<<s.p<<" "<<s.p[1]<<endl;
cout<<&p[1]<<" "<<&s.p<<" "<<&s.p[1]<<endl;
s.p[1]=1;
cout<<s.p<<" "<<&s.p<<endl;
//s.p[0]=2;崩溃
//*s.p=2;s.p[0]相当于*s.p
}
结果如下:

《程序员面试宝典第四版》笔记4

面试例题5:有20个数组,每个数组里面有500个数,升序排列,求出这10000个数字中最大的500个。 求复杂度
解析:20个数组的最大元素全部进堆。 每次取最大的一个的时候,从最大元素对应的数组里取下来一个放进堆里。 堆里一直最多有20个数,充分利用20个数组的有序性。
答案:复杂度500*log(20)

面试例题2:试用多态实现线性表(队列、 串、 堆栈),要求具备线性表的基本操作:插入、 删除、 测长等。(自己写着玩的,哈哈哈哈)

#include <iostream>
using namespace std;
//模拟vector中的某些性能
template<typename T>
class MyVector
{
static const size_t volume=10;
private:
size_t len;
size_t cap;
T *data;
public:
MyVector()
{
len=0;
cap=volume;
data=new T[cap];
}
MyVector(const MyVector &other)
{
len=other.len;
cap=other.cap;
data=new T[cap];
for(size_t i=0;i<len;i++)
data[i]=other.data[i];
}
~MyVector()
{
delete []data;
}
size_t length()
{
return len;
}
size_t capicity()
{
return cap;
}
void push(const T &element)
{
if(len<cap)
{
data[len]=element;
len++;
}
else
{
cap*=2;
T *tmp=data;
data=new T[cap];
for(size_t i=0;i<len;i++)
data[i]=tmp[i];
data[len]=element;
len++;
delete []tmp;
}
}
void pop()
{
if(len>0)
len--;
}
void gettop(T &element)
{
if(len>0)
element=data[len-1];
}
T& operator[](size_t i)
{
if(i<len)
return data[i];
}
};
int main()
{
MyVector<int> myvector;
for(int i=1;i<=30;i++)
{
myvector.push(i);
}
MyVector<int> myvector1=myvector;
for(int i=1;i<=30;i++)
{
cout<<myvector1[i-1]<<" ";
}
}

面试例题2:1~9的9个数字,每个数字只能出现一次,要求这样一个9位的整数:其第一位能被1整除,前两位能被2整除,前三位能被3整除……依次类推,前9位能被9整除。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void permutation(vector<vector<int>>& res, vector<int>& num, int index)
{
if(index >= num.size())
{
res.push_back(num);
return;
}
for(int i = index; i < num.size(); i++)
{
swap(num[i], num[index]);
permutation(res, num, index+1);
swap(num[index], num[i]);
}
}
vector<long long> Compute()
{
vector<long long>tmp;
vector<vector<int>>res1;
vector<vector<int>>res2;
int arr1[]={1,3,7,9};
int arr2[]={2,4,6,8};
vector< int > ivec1(arr1,arr1+4);
vector< int > ivec2(arr2,arr2+4);
permutation(res1,ivec1,0);
permutation(res2,ivec2,0);


size_t len=res1.size();
for (size_t i=0;i<len;i++)
{
for(size_t j=0;j<len;j++)
{
long long tempnum=0;
size_t k;
for (k=0;k<9;k++)
{
if(k==4)
{
tempnum=tempnum*10+5;
}
else
{
if(k<4&&k%2==0)
tempnum=tempnum*10+res1[i][k/2];
if(k>4&&k%2==0)
tempnum=tempnum*10+res1[i][k/2-1];
if(k%2==1)
tempnum=tempnum*10+res2[j][(k+1)/2-1];
}
if(tempnum%(k+1)!=0)
break;
}
if(k==9)
tmp.push_back(tempnum);
}
}
return tmp;
}


int main()
{
vector<long long> res=Compute();
for(size_t i=0;i<res.size();i++)
cout<<res[i]<<" ";
}


面试例题1:求一个字符串中连续出现次数最多的子串,请给出分析和代码。
#include <iostream>
#include <cstring>
#include <utility>
#include <string>
#include <vector>
using namespace std;


pair<int, string> fun(const string& str)
{
vector<string> subs;
int len = str.size();
for (int i = 0; i < len; i++)
{
subs.push_back(str.substr(i));
}


int count = 1;
int maxCount = 1;
string sub;


for (int i = 0; i < len; i++)
{
for (int j = i + 1; j < len; j++)
{
count = 1;
if (subs[i].substr(0, j - i) == subs[j].substr(0, j - i))
{
++count;
//j-i为子串长度
for (int k = j + j - i; k < len; k += j - i)
{
if (subs[i].substr(0, j - i) == subs[k].substr(0, j - i))
{
++count;
}
else
{
break;
}
}
if (count > maxCount)
{
maxCount = count;
sub = subs[i].substr(0, j - i);
}
}
}
}


return make_pair(maxCount, sub);
}


int main()
{
string str="abcabcabcabdabdabdabdc";
pair<int, string> rs;


rs = fun(str);
cout<<rs.second<<":"<<rs.first<<endl;
return 0;
}

面试例题2:输入一行字符串,找出其中出现的相同且长度最长的字符串,输出它及其首字符的位置。 如“yyabcdabjcabceg”,输出结果应该为abc和3。
#include <iostream>
#include<string>
#include<vector>
using namespace std;
pair<string,int> FindSameLongest(const string &str)
{
size_t len=str.length();
size_t i;
string tmp;
for (size_t j=len-1;j>=1;j--)
{
for (i=0;i<len;i++)
{
if(j+i<=len)
{
tmp=str.substr(i,j);
size_t found=str.rfind(tmp);
if (found!=i&&found!=string::npos)
{
return make_pair(tmp,i+1);
}
}
}
}
}
int main()
{
string str="yyabcdabjcabceg";
pair<string,int>res=FindSameLongest(str);
cout<<res.first<<" "<<res.second<<endl;
}

面试例题3:const char* strstr(const char* string, const char* strCharSet);(请写一个函数来模拟C++中的strstr()函数:该函数的返回值是主串中字符子串的位置以后的所有字符。 请不要使用任何C程序已有的函数来完成。 )

#include <iostream>
using namespace std;
size_t MyStrlen(const char* str)
{
size_t len=0;
while(str[len++]!='\0');
return len-1;
}
const char* MyStrStr(const char* string, const char* strCharSet)
{
size_t len=MyStrlen(string);
size_t sublen=MyStrlen(strCharSet);
const char *p;
for(size_t i=0;i<len;i++)
{
size_t j;
for(j=0;j<sublen;)
{
if(string[i+j]==strCharSet[j])
j++;
else break;
}
if(j==sublen)
{
p=string+i;
break;
}
}
return p;
}
int main()
{
char *string="I Love SEU ,And You?";
char *strCharSet="SEU";
const char *res=MyStrStr(string,strCharSet);
cout<<res<<endl;
}