平常看书遇到的一些笔试面试题,有些是觉得自己没掌握的,代码都是自己写的,还是菜鸟级别,大家莫笑~有些是自己把代码写出来记录的,鞭策自己多写平常遇到的感触。一直往下加,知道找到工作那一天~嘿嘿~
1.写个类A,声明类A指针指向NULL,调用类A的方法会有什么后果,编译通过吗?
因为非虚函数的地址对编译期来说“静态”的,也就是函数地址在编译期就已经确定了,实例地址对于非虚函数
只是那个 this 指针参数。
所以只要不访问类的实例数据就没什么问题。而虚函数的地址,
是先到实例的地址前面去查找它的虚函数表所在的地址。
然后从虚函数表里取出该函数所对应的元素(虚函数表是一个函数指针数组)来call的。
(当然一个已知的类的虚函数表的内容也是编译期静态的,但不同类的虚函数表内容不同,即运行时多态的基础)
所以实例如果为NULL,是个有特殊意义的值,是会触发运行时错误的。
2.给定一个函数rand()能产生0到n-1之间的等概率随机数,问如何产生0到m-1之间等概率的随机数?先把问题特殊化,例如原题变为给定一个函数rand5,该函数可以随机生成1-5的整数,且生成概率一样。现要求使用该函数构造函数rand7(),使函数rand7()可以随机等概率的生成1-7的整数。
方法:利用rand5()函数生成1-25之间的数字,然后将其中的1-21映射成1-7,丢弃22-25。例如生成(1,1),(1,2),(1,3),则看成rand7()中的1,如果出现剩下的4种,则丢弃重新生成。
现在来看原题把rand()视为N进制的一位数产生器,那么可以使用rand()*N+rand()来产生2位的N进制数,以此类推,可以产生3位,4位,5位...的N进制数。这种按构造N进制数的方式生成的随机数,必定能保证随机概率平均。
int random(int m , int n)
{
int k = rand();
int max = n-1;
while((max+1) < m) )
{
k = k*n + rand(); //每次增加一位的值每一位的值都是随机取的
max = max*n + n-1; //当最大值大于m之后则位数确定了。即25大于7之后退出循环
if((max+1>=m && k >= (max+1)/m*m)
//当k值大于m的(max+1)/m倍即如rand7中的k大于21时重新取随机数
{
k=0;
max=0;
}
}
return k%m;
}
3.求二叉树中距离最远的两个点。?
int max=0;
Node* Iroot=Null;
int maxD(Node* root)
{
if(root->left==null &&root->right==null)
{
return 0;
}
else
{
if(root->left!null )
leftD=maxD(root->left);
}
if(root->right!null )
rightD=maxD(root->right);
}
if((leftD+rightD)>max)
{
max=leftD+rightD;
Iroot=root;
}
return leftD>=rightH?(leftD):(rightD);
}
4. .
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order。一句话,即为螺旋矩阵问题。
举个例子,给定如下的一个矩阵:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
你应该返回:[1,2,3,6,9,8,7,4,5]。如下图所示,遍历顺序为螺旋状:
#include<iostream>
using namespace std;
//int a[][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 ,10,11,12,13,14,15,16};
int a[][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
//int a[][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
void print(int m,int n)
{
int MT =0, NT = 0; //NT,MT是旋转一圈后+1,的值
int i = 0, j = 0; //i,j是旋转中的值
while ((MT <= m / 2) && (NT <= n / 2))
{
if (i == MT)
{
while (j<(n-NT-1))
{
cout << a[i][j++];
}
}
if (j == n-NT-1)
{
while (i<(m-MT-1))
{
cout << a[i++][j];
}
}
if (i ==(m- MT-1))
{
while (j>(NT))
{
cout << a[i][j--];
}
}
if (j == (NT))
{
while (i>(MT+1))
{
cout << a[i--][j];
}
}
MT++;
NT++;
}
if(n%2==0)cout << a[i][j]; //当列为偶数时,一圈当中的最后一次不转
}
void main()
{
print(5,3);
}
5.//华为划屏
string touchScreen(int x1, int y1, int x2, int y2)
{
if (x1 == x2&&y1 == y2)
{
return "CLICK";
}
if (x2 >= x1)
{
if (x2 == x1)
{
if (y2 > y1)
{
return "down";
}
else
{
return "up";
}
}
if ((y2 - y1) / (x2 - x1) >= -1 && (y2 - y1) / (x2 - x1) <= 1)
{
return "right";
}
if ((y2 - y1) / (x2 - x1) <-1)
{
return "up";
}
if ((y2 - y1) / (x2 - x1) >1)
{
return "down";
}
}
if (x2 < x1)
{
if ((y2 - y1) / (x2 - x1) >= -1 && (y2 - y1) / (x2 - x1) <= 1)
{
return "left";
}
if ((y2 - y1) / (x2 - x1) <-1)
{
return "down";
}
if ((y2 - y1) / (x2 - x1) >1)
{
return "up";
}
}
}
//华为字符压缩
void stringZip(const char *pInputStr, long lInputLen, char *pOutputStr)
{
int num = 1;
int outNum = 0;
for (int i = 0; i < lInputLen; i++)
{
if (pInputStr[i] == pInputStr[i + 1])
{
++num;
continue;
}
else
{
if (num>9)
{
while( (num/10)>0)
{
pOutputStr[outNum++] = num/10 + '0';
num = num % 10;
}
}
if (num > 1&& num<10)
{
pOutputStr[outNum++] = num + '0';
pOutputStr[outNum++] = pInputStr[i];
num = 1;
}
else
{
pOutputStr[outNum++] = pInputStr[i];
}
}
}
pOutputStr[outNum] = '\0';
}
//华为走路有洞
string hole(int* in,int length)
{
for (int i = 0; i < length-1; i=i+2)
{
if (in[i]>=500)
{
return "yes";
}
int meter1 = in[i] * 100 ;
int meter2 = in[i] * 100 + in[i + 1];
if ((meter1 % 65 + in[i + 1])>65) return "no";
}
return "yes";
}
//暴风影音查找最大字串
string findMax(string lIn, string rIn)
{
int max = 0, num = 1;
int l = lIn.size(), r = rIn.size();
string out = "";
for (int i = 0; i <l; i++)
{
for (size_t j = 0; j < r; j++)
{
if (lIn.at(i)==rIn.at(j))
{
string temp = "";
temp = lIn[i];
int p =i+1, q = j+1;
while (p<l&&q<r&&lIn.at(p) == rIn.at(q))
{
temp = temp+lIn[p] ;
p++; q++; num++;
}
if (num>max)
{
out = temp;
max = num;
num = 1;
}
}
}
}
return out;
}
//小米字符串的四则运算 //先将四则运算转化为后缀排序 再运算~
map<char, int> m;
int math(char *in)
{
char c[100];
//char* c=new char[strlen(in)+1];
int p = 0;
stack<pair<char,int>> fuhaos;
int length = strlen(in);
for (int i = 0; i < length; i++)
{
if (in[i]<='9'&&in[i]>='0')
{
c[p++]=(in[i]);
}
else
{
if (in[i]=='(')
{
for (map<char, int>::iterator it = m.begin(); it != m.end(); it++)
{
(it->second)++;
(it->second)++;
}
continue;
}
if (in[i] == ')')
{
for (map<char, int>::iterator it = m.begin(); it != m.end(); it++)
{
(it->second)--;
(it->second)--;
}
continue;
}
if (fuhaos.empty())
{
fuhaos.push(pair<char, int>(in[i], m.find(in[i])->second));
continue;
}
if (m.find(in[i])->second >= fuhaos.top().second)
{
fuhaos.push(pair<char, int>(in[i], m.find(in[i])->second));
}
else
{
c[p++] = fuhaos.top().first;
fuhaos.pop();
fuhaos.push(pair<char, int>(in[i], m.find(in[i])->second));
}
}
}
while(!fuhaos.empty())
{
c[p++] = fuhaos.top().first;
fuhaos.pop();
}
return 0;
}
extern "C" int _cdecl wmain(int argc, wchar_t* argv[])
{
m.insert(make_pair<char, int>('+', 0));
m.insert(make_pair<char, int>('-', 0));
m.insert(make_pair<char, int>('*', 1));
m.insert(make_pair<char, int>('/', 1));
//m.insert(make_pair<char, int>('(', -1));
//m.insert(make_pair<char, int>(')', 2));
char* in = "1*5+(2+(3-4))";
math(in);
}
//用位运算求除法
int fun(int a, int b)
{
int res = 0; int lef = a;
while (lef >= b)
{
int m = 1;
while (b*m <= (lef))
{
m = m << 1;
}
res += m >> 1;
lef -= b*(m>>1);
}
return res;
}
6.题目B:亲友团问题
//题目B:亲友团问题
//时间限制(普通 / Java) :6000MS / 18000MS 运行内存限制 : 65536KByte
//问题描述
//在2014“华为杯”南邮大学生团体歌唱大赛每一个轮比赛现场,众多亲友团是一道亮丽的风景,他(她)们或来助威、或来观摩、或来刺探对手情报,不同亲友团之间偶尔还起冲突。为避免安全问题,主办方在赛场会划分许多独立区域,每一个区域安置一个亲友团,现在请你根据主办方提供的比赛现场信息,预测至多需要划分出多少个独立区域。
//我们将主办方提供的比赛现场信息进行简化,从1开始按顺序给进入比赛现场的每位亲友分配一个编号,依次为1、2、...、K,K为亲友总数,为保护隐私,主办方只能告诉你M组两个不同亲友属于同一亲友团信息,这些信息有可能重复。
//问题输入
//输入包括多个测试用例,首先给出测试用例数N,接着给出N个测试用例,1≤N≤100。
//每一个测试用例包括M + 1行,首先给出两个整数K和M;再依次给出M行,每行给出两个不同正整数i和j,表示两个不同亲友i和j属于同一亲友团,i≠j,1≤i≤K,1≤j≤K,,1≤K≤10000,1≤M≤10000。
//问题输出
//输出包括多行,对于每个测试用例,输出一行,给出至多需要划分出的独立区域数量。
//样例输入
//2
//3 1
//1 2
//3 2
//1 2
//2 3
//样例输出
//2
//1
#include<iostream>
#include<map>
#include<vector>
using namespace std;
//int in[][2] = { 1, 2 ,2,3};
int findPlace(const int k, const int m,int** in)
{
vector<int> v;
int num = 0;
for (int i = 0; i < m; i++)
{
if (v.end() == find(v.begin(), v.end(), in[i][0]) && v.end() == find(v.begin(), v.end(), in[i][1])) //如果交集里面没有+1组
{
num++;
v.push_back(in[i][0]);
v.push_back(in[i][1]);
}
else
{
v.push_back(in[i][0]);
v.push_back(in[i][1]);
}
}
for (int i = 1; i < k+1; i++)
{
if (v.end() == find(v.begin(), v.end(), i))
{
num++;
}
}
return num;
}
void main()
{
int N, K, M;
cin >> N;
int*** allIn = new int**[N];
for (int i = 0; i < N; i++)
{
cin >> K >> M;
allIn[i] = new int*[M];
for (int j = 0; j < M; j++)
{
allIn[i][j] = new int[2];
cin >> allIn[i][j][0] >> allIn[i][j][1];
}
findPlace(K, M, allIn[i]);
}
}