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

面试例题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
}
结果如下:



面试例题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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值