您的位置:首页 > 职场人生

Microsoft经典面试题集锦

2013-03-16 14:44 260 查看
一 检查字符串是否为整数,是则输出该整数



#include <iostream>
#include <string>
#include <cctype>

using namespace std;

const int max = 10;
bool checkNum(string &str) {
string::iterator it;
int i;
long s = 0;
for(it = str.begin(), i = 0; it != str.end() && i < max; i++, it++) {
if(!isdigit(*it)) return false;
s = s*10 + (*it) - '0';
}
if(i >= max) {
cerr<<"整数溢出!"<<endl;
}
cout<<str<<"对应的整数是:"<<s<<endl;
return true;
}

void main() {
string str;
cin>>str;
if(!checkNum(str)) {
cerr<<str<<"不是整数"<<endl;
}
}
















二 在排序好的整数数组中查找给定数出现的次数



#include <iostream>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <ctime>

using namespace std;

#define ERROR -1
const int M = 1000;
class Solution {
private:
int N;
vector<int>v;

int BinaryLocate(int low, int high, int x) {
int mid = (low + high) / 2;
if(low <= high) {
if(v[mid] == x) return mid;
else if(v[mid] > x) return BinaryLocate(low, mid-1, x);
else return BinaryLocate(mid+1, high, x);
}
else return ERROR;
}
public:
Solution(int n) {
if(n <= 0 || n > M) {
cerr<<"参数错误, 程序退出!"<<endl;
exit(1);
}
N = n;
int i;
srand(unsigned(time(0)));
for(i = 0; i< N; i++) {
int x = rand() % N;
v.push_back(x);
}
sort(v.begin(), v.end());
copy(v.begin(), v.end(), ostream_iterator<int>(cout," "));
}

int JustDoIt(const int e) {
int i = BinaryLocate(0, v.size() - 1, e);
if(i < 0) {
cerr<<"不能找到"<<e<<endl;
return ERROR;
}
int cnt =1;
int j = i;
/*
* j指向第一次出现v[i]的位置,如 1 3 3 3 4 5 6
* j会指向位置1
*/
while(j > 0 && v[j] == v[j-1]) j--;
i = j;
while(i < v.size() -1 && v[i] == v[i+1]) {
cnt++;
i++;
}
return cnt;
}
};

void main() {
int N = 20;
Solution s(N);
int e;
cout<<"请输入0到"<<N-1<<"之间的整数:"<<endl;
cin>>e;
if(!cin.good()) {
cerr<<"输入错误!"<<endl;
exit(1);
}
int cnt = s.JustDoIt(e);
if(cnt != ERROR) {
cout<<e<<"出现的次数为:"<<cnt<<endl;
}
}






三 平面上N个点,每两个点都确定一条直线,求出斜率最大的那条直线所通过的两个点(斜率不存在的情况不考虑)。



#include <iostream>
#include <cstdlib>
#include <vector>
#include <algorithm>

using namespace std;

const double min = - 99999;   // 当两个点的横坐标相同时, 它们的斜率为min

const double minNum = -10000;  // 最小的数
const double maxNum = 10000;  // 最大的数

class Point {
public:
double x;
double y;
Point(double X = 0, double Y = 0) {
x = X;
y = Y;
}
bool operator < (const Point & p) {
return x < p.x;
}
friend ostream operator <<(ostream &os, const Point &point) {
os<<"["<<point.x<<","<<point.y<<"]"<<endl;
return os;
}
};

/*
* 先对点向量按横坐标排序, 然后计算排序后相邻点的斜率
*/

class Solution {
private:
vector<Point>v;   // 点向量
int n;            // 点的个数
double maxK;      // 最大的斜率
public:
Solution(int N) {
if(N <= 0) {
cerr<<"参数不合法, 程序退出!"<<endl;
exit(1);
}
n = N;
int i;
double x, y;
for(i = 0; i < n; i++) {
cout<<"第"<<i<<"个点:"<<endl;
cin>>x>>y;
if(!cin.good()) {
cout<<"输入不合法, 程序退出!"<<endl;
exit(1);
}
if(x < minNum || x > maxNum) {
cerr<<"参数不合法, 程序退出!"<<endl;
exit(1);
}
if(y < minNum || y > maxNum) {
cerr<<"参数不合法, 程序退出!"<<endl;
exit(1);
}
Point p = Point(x, y);
v.push_back(p);
}
maxK = 0;
}
void JustDoIt() {
sort(v.begin(), v.end());     // 按点的横坐标x快速升序排序
int len = n - 1;
double *k = new double(len);    // 斜率数组

int i;
for(i = 0; i < n-1; i++) {
k[i] = slop(v[i], v[i+1]);      // 求出相邻两个点的斜率
}
maxK = *max_element(k, k + len);      // 求出数组k中最大值
i = max_element(k, k + len) - k;	    // 求出数组k中最大值的索引
showmaxK();

cout<<v[i];                         // 求出哪两个点的斜率最大
cout<<v[i+1];
}
double slop(const Point& start, const Point& end) {
if(end.x - start.x == 0) return min;
return 1.0 * (end.y - start.y) / (end.x - start.x);
}
void showV() {
vector<Point>::iterator it;
for(it = v.begin(); it != v.end(); it++) {
cout<<*it;
}
}
void showmaxK() {
cout<<"最大斜率是:"<<maxK<<endl;
}
};

void main() {
Solution s(10);
s.JustDoIt();
}


测试:








四一个整数数列,元素取值可能是0~65535中的任意一个数,相同数值不会重复出现。0是例外,可以反复出现。
请设计一个算法,当你从该数列中随意选取5个数值,判断这5个数值是否连续相邻。
注意:
- 5个数值允许是乱序的。比如: 8 7 5 0 6
- 0可以通配任意数值。比如:8 7 5 0 6 中的0可以通配成9或者4
- 0可以多次出现。
- 复杂度如果是O(n2)则不得分。




#include <iostream>
#include <cstdlib>
#include <vector>
#include <ctime>
#include <algorithm>

using namespace std;

const int Max = 65535;
class Solution {
private:
vector<int>v;
vector<int>selection;
int n;
int m;
public:
Solution(int N) {
if(N <= 0) {
cerr<<"参数不合法, 程序退出!"<<endl;
exit(1);
}
if(!cin.good()) exit(1);
n = N;
int i;
srand(unsigned(time(NULL)));
for(i = 0; i < n; i++) {
int e = rand() % Max;
if(v.empty() == true) v.push_back(e);
else if(e == 0) {
v.push_back(e);
}
else if(find(v.begin(), v.end(), e) == v.end())  {
v.push_back(e);
}
}
}
/*
* 随机选择M个整数
*/
void RandomSelectM(int M) {
if(M <= 0) {
cerr<<"参数不合法, 程序退出!"<<endl;
exit(1);
}
if(!cin.good()) exit(1);
m = M;
srand(unsigned(time(NULL)));
int i = 0;
int j;
while(i < m) {
j = rand() % v.size();               //随机产生一个索引号
if(selection.empty() == true) {
selection.push_back(v[j]);
i++;
}
/*
* 刚随机选择的数之前没有选择过
*/
else if(find(selection.begin(), selection.end(), v[j]) == selection.end()) {
selection.push_back(v[j]);
i++;
}
}
}

void IsSequence() {
int Max = *max_element(selection.begin(), selection.end());    // 找到数组中最大值
int Min = *min_element(selection.begin(), selection.end());
if(Max - Min <= m - 1) {
cout<<"这"<<m<<"个整数连续"<<endl;
}
else cout<<"这"<<m<<"个整数不连续"<<endl;
}
void show() {
vector<int>::iterator it;
cout<<"这"<<n<<"个数是:";
for(it = v.begin(); it != v.end(); it++) {
cout<<*it<<" ";
}
cout<<endl;
cout<<"从这"<<n<<"个数中选择"<<m<<"个数是:";
for(it = selection.begin(); it != selection.end(); it++) {
cout<<*it<<" ";
}
cout<<endl;
}
};
void main() {
Solution s(10);
s.RandomSelectM(5);
s.show();
s.IsSequence();
}




五 设计一个算法,找出二叉树上任意两个结点的最近共同父结点。复杂度如果是O(n2)则不得分。



#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

template<class T>
/*
* 二叉树结点类
*/
class BinNode {
public:
T data;
BinNode<T>*lchild;
BinNode<T>*rchild;
BinNode<T>(T e =NULL, BinNode<T>*left = NULL, BinNode<T>*right = NULL) {
data = e;
lchild = left;
rchild = right;
}
BinNode<T>(const BinNode<T> &binNode) {
data = binNode.data;
lchild = binNode.lchild;
rchild = binNode.rchild;
}
BinNode<T> operator = (const BinNode<T> &binNode) {
data = binNode.data;
lchild = binNode.lchild;
rchild = binNode.rchild;
return *this;
}
};

/*
* 二叉树类
*/
template<class T>
class BinTree {
private:
BinNode<T>*root;       // 二叉树根结点指针
BinNode<T>*result;     // 最近公共父结点指针

/*
* 递归构造二叉树
*/
void CreateBinTree(BinNode<T>*&p) {
T data;
cin>>data;
if(data != "#") {
p = new BinNode<T>(data);
CreateBinTree(p->lchild);
CreateBinTree(p->rchild);
}
}
/*
* 前序遍历二叉树
*/
void Tranvser(BinNode<T>*p) {
if(p != NULL) {
cout<<p->data<<" ";
Tranvser(p->lchild);
Tranvser(p->rchild);
}
}
bool NearestParent(BinNode<T>*root, BinNode<T>*parent, BinNode<T>*&result, const T&a, const T&b) {
/*
* left = true 表示a或b在当前结点的左子树中
*/
bool left = false;
/*
* right = true 表示a或b在当前结点的右子树中
*/
bool right = false;
/*
* 从当前结点的左子树返回后, left = true表示a或b在它的左子树中
*/
if(!result && root->lchild) left = NearestParent(root->lchild, root, result, a, b);
/*
* 从当前结点的右子树返回后, right = true表示a或b在它的右子树中
*/
if(!result && root->rchild) right = NearestParent(root->rchild, root, result, a, b);
/*
* cur = true 表示a或b就是当前正在访问的结点
*/
bool cur = false;

// 当root指向的当前结点是a或b时
if(root->data == a || root->data == b) {
cur = true;
}
// 此时a和b位于同一分支或者a和b位于不同分支
if(!result && cur + left + right == 2) {
if(cur == true) {      // 此时a和b同时位于左分支或右分支
result = parent;
}
else result = root;
}
return left | right | cur;
}
public:
BinTree() {
root = NULL;
CreateBinTree(root);
}
void Tranvser() {
Tranvser(root);
}
void NearestParent(const T&a, const T&b) {
result = NULL;
NearestParent(root, NULL, result, a, b);
}
void getResult() {
cout<<result->data<<endl;
}
};

void main() {
BinTree<string>binTree;
cout<<"输入的二叉树是:";
binTree.Tranvser();
cout<<endl;
string a, b;
cout<<"请输入两个结点值:";
cin>>a>>b;
binTree.NearestParent(a, b);
binTree.getResult();
cout<<a<<"和"<<b<<"最近公共父结点是:";
binTree.getResult();
}


测试:






六 一棵排序二叉树,令
f=(最大值+最小值)/2, 设计一个算法,找出距离f值最近、大于f值的结点。

#include <iostream>
#include <cstdlib>

using namespace std;

template<class T>
class BSTNode {
public:
T data;
BSTNode<T>*lchild;
BSTNode<T>*rchild;

BSTNode(const T &e, BSTNode<T>*left = NULL, BSTNode<T>*right = NULL) {
data = e;
lchild = left;
rchild = right;
}

BSTNode(const BSTNode<T> &bst) {
data = bst.data;
lchild = bst.lchild;
rchild = bst.rchild;
}

BSTNode<T>& operator =(const BSTNode<T> &bst) {
data = bst.data;
lchild = bst.lchild;
rchild = bst.rchild;
return *this;
}
};

template<class T>
class BST {
friend class Solution;
private:
BSTNode<T>*root;
int N;
/*
* 后序遍历
*/
void tranverseBST(BSTNode<T>*root) {
if(root) {
tranverseBST(root->lchild);
cout<<root->data<<" ";
tranverseBST(root->rchild);
}
}
/*
* 插入结点
*/
void insertBST(BSTNode<T>*&root, const T& e) {
if(root == NULL) {
root = new BSTNode<T>(e);
}
else if(e >= root->data) {
insertBST(root->rchild, e);
}
else insertBST(root->lchild, e);
}

public:
BST() {
root = NULL;
}

void createBST(int n) {
if(n <= 0) {
cerr<<"参数错误, 程序退出!";
exit(1);
}
int i;
T e;
for(i = 0; i < n; i++) {
cout<<"请输入第"<<i<<"个值:";
cin>>e;
insertBST(root, e);
}
}
void tranverseBST() {
tranverseBST(root);
}
};

class Solution {
private:
BST<double>bst;
double max;
double min;
double f;
bool find;
BSTNode<double>*result;

void Setmax(BSTNode<double>*node) {
while(node->rchild) {
node = node->rchild;
}
max = node->data;
}

void Setmin(BSTNode<double>*node) {
while(node->lchild) {
node = node->lchild;
}
min = node->data;
}

void Setf() {
f = (min + max)/2;
}

void Setresult(BSTNode<double>*node) {
if(node) {
if(find == false) {
Setresult(node->lchild);
}
if(find == false && node->data > f) {
result = node;
find = true;

}
if(find == false) {
Setresult(node->rchild);
}
}
}
public:
Solution(int n):max(0), min(0), result(NULL), find(false) {
bst.createBST(n);

}

void JustDoIt() {
Setmax(bst.root);
Setmin(bst.root);
Setf();
Setresult(bst.root);
}
void show() {
cout<<"最大值是:"<<max<<endl;
cout<<"最小值是:"<<min<<endl;
cout<<"中值是:"<<f<<endl;
cout<<"最接近中值的结点是:"<<result<<endl;
cout<<"最接近中值的值是:"<<result->data<<endl;
}
};

void main() {
Solution s(6);
s.JustDoIt();
s.show();
}

测试:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: