分类: C/C++
2008-10-20 15:59:28
(说明:这些题就不是什么花样了,考的是你的基础知识怎么样。再聪明而没有实学的人都将会被这些题所淘汰。)
1.链表和数组的区别在哪里?
ANSWER 主要在基本概念上的理解。但是最好能考虑的全面一点,现在公司招人的竞争可能就在细节上产生,谁比较仔细,谁获胜的机会就大。
2)数组一旦显式的被申明后,其大小就固定了,不能动态进行扩充。而链表则可以,可以动态生成节点并且添加到已有的链表后面。
3) …… (大家一起想想)
2.编写实现链表排序的一种算法。说明为什么你会选择用这样的方法?
ANSWER 链表通常是插入排序,为什么呢?在数组中插入排序实现时会大量的移动数据从而删除位置不正确的元素,这是顺序表删除操作的低效性。从数学的角度,顺序表(即数组)的删除操作是O(n).链表就不同,由于其存储位置的不固定性,其删除固定位置的元素只需要O(1)的时间,所以整体性能上获得比较大的提高。
3.编写实现数组排序的一种算法。说明为什么你会选择用这样的方法?
ANSWER 排序算法非常成熟了,实际上排序是研究算法的很有效例子。回答的时候尽量找一些比较有技术性的算法,比如堆排序或者快速排序,如果写冒泡什么的,别人都会写,也就显示不出你的优秀了。当然一定要注意给定的条件。不至于三个数让你排序,你搞个快排,这就有点“宰牛刀杀鸡”了。
4.请编写能直接实现strstr()函数功能的代码。
ANSWER 首先要知道strstr()这个函数是干什么的,自己去查查C语言的书,一般附录后面会给出C语言标准库的。这个题目实际上也是一类重要的算法门类,叫做 “字符串的模式匹配”。它有很多的现成算法,其中最简单的要数朴素的匹配算法,还有KMP,BM这些高级算法,笔试估计是来不及写的。下面给出朴素的匹配算法。
int stringMatching(char* pattern,char* text)
{
int pLen = strlen(pattern),tLen = strlen(text);
for(int i = 0;i <= tLen - pLen;i++){
for(int j = 0; pattern[j] == text[i + j];j++);
if(j == pLen) return i;
}
return -1; // Not found
}
5.编写反转字符串的程序,要求优化速度、优化空间。
ANSWER:循环当然是最简单的。
void reverseString(char* str)
{
int n = strlen(str);
for(int i = 0;i < n/2;i++)
{int t = str[i];str[i] = str[n - i - 1];str[n - i - 1] = t;}
}
6.在链表里如何发现循环链接?
7.写一个函数,检查字符是否是整数,如果是,返回其整数值。(或者:怎样只用4行代码编写出一个从字符串到长整形的函数?)
分析 :简单!扫描一遍,每次生成对应整数的最高位。一行也就搞定了!
long convert(char* s_string,long s_integer)
{
for(int sLen = strlen(s_string), i = 0; i < sLen;s_integer += (s_string[i++] - '0')*pow(10,sLen - i - 1));
return s_integer;
}
8.给出一个函数来输出一个字符串的所有排列。
ANSWER 简单的回溯就可以实现了。当然排列的产生也有很多种算法,去看看组合数学,还有逆序生成排列和一些不需要递归生成排列的方法。印象中Knuth的< TAOCP>第一卷里面深入讲了排列的生成。这些算法的理解需要一定的数学功底,也需要一定的灵感,有兴趣最好看看。
void permStr(char* str,int i)
{
if(i == strlen(str) - 1)
printf("%s\n",str);
else
{
for(int j = i;j < strlen(str);j++)
{
swap(&str[i],&str[j]);
permStr(str,i + 1);
swap(&str[i],&str[j]);
}
}
}
9.给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。
anSwer 记住,这种题目往往就是考你对边界的考虑情况。编程除了技术上的熟练以外,细心也是非常重要的。其实很多编程的大师可能并不是有特别的技术,往往就是他们非常的耐心和细心,记住:编程是计算机科学中最基本的工作,它是最容易去掌握的,耐心点,细心点你一定能够学好它。代码看下面:
char* myStrcpy(char* s,char* a,char* b,char n)
{
int aLen = strlen(a),bLen = strlen(b);
if(n > aLen || n > bLen)
return NULL; // Error
for(int i = 0;i < aLen + bLen - n;i++)
if(i < aLen - n) s[i] = a[i];
else s[i] = b[i - aLen + n];
s[i] = '\0';
return s;
}
10.怎样编写一个程序,把一个有序整数数组放到二叉树中?
void insertNode(bTree** root,int val)
{
bTree* newNode = (bTree* ) malloc(sizeof(bTree));
newNode->data = val;
newNode->lChild = NULL;
newNode->rChild = NULL;
if(!(*root))
*root = newNode;
else if(newNode->data < (*root)->data)
insertNode(&(*root)->lChild,val);
else
insertNode(&(*root)->rChild,val);
}
11.怎样从顶部开始逐层打印二叉树结点数据?请编程。
ANSWER 二叉树的层次遍历没什么好说的,如果你不会还是早点把基础复习一下。一个劲的往后学,才会发现原来最最重要的还是以前最基础最简单的。
typedef struct myBinaryTree
{
int data;
struct myBinaryTree* lChild;
struct myBinaryTree* rChild;
} bTree;
struct myQueen
{
bTree* que[QSIZE];
int front;
int rear;
} binQueue; // Global var
void initQueue()
{
// front == real makes the queue empty
binQueue.rear = QSIZE - 1;
binQueue.front = binQueue.rear;
for(int i = 0;i < QSIZE;i++)
binQueue.que[i] = NULL;
}
int enQueue(bTree* newNode)
{
if(binQueue.front >= 1)
binQueue.que[binQueue.front--] = newNode;
else return 0;
return 1;
}
bTree* deQueue()
{
int t;
if(binQueue.front != binQueue.rear){
t = binQueue.rear;
binQueue.rear--;
return binQueue.que[t];
}
else return NULL;
}
int levelTraversal(bTree** root)
{
initQueue();
bTree* lc = (bTree* ) malloc(sizeof(bTree));
bTree* rc = (bTree* ) malloc(sizeof(bTree));
bTree* p = (bTree* ) malloc(sizeof(bTree));
if((!lc) || (!rc) || (!p)){
printf("OVERFLOW\n");
exit(OVERFLOW); // Allocation Error
}
p = *root;
if(!p) {
printf("Empty Tree,build it first !\n");
return 0;
}
enQueue(p); // enqueue the root of the tree
while (binQueue.front != binQueue.rear){
p = deQueue();
printf("%d ",p->data);
lc = p->lChild;
rc = p->rChild;
if(lc != NULL)
enQueue(lc);
if(rc != NULL)
enQueue(rc);
}
printf("\n");
return 1;
}
12.怎样把一个链表掉个顺序(也就是反序,注意链表的边界条件并考虑空链表)?
typedef struct listNode
{
struct listNode* link;
int data;
}node;
node* getNode(node* newNode,int val)
{
if(!newNode)
exit(OVERFLOW);
newNode->link = NULL;
newNode->data = val;
return newNode;
}
/*
Insert a new node after p
*/
int insertNode(node* prev,node* newNode)
{
if(!prev) return 0;
newNode->link = prev->link;
prev->link = newNode;
return 1;
}
/*
delete the node after the node prev
*/
int eraseNode(node*prev,node* p)
{
if(p == NULL)
return 0;
prev->link = p->link;
free(p);
return 1;
}
void buildList(node* head)
{
int value;
node* newNode = (node* ) malloc(sizeof(node));
node* p = head;
scanf("%d",&value);
while(value != -1){
newNode = getNode(newNode,value);
insertNode(p,newNode);
p = p->link;
newNode = (node* ) malloc(sizeof(node));
scanf("%d",&value);
}
}
int reverseList(node* head)
{
node* p = head->link;
node* q = p->link;
if(p == NULL){
printf("The list is empty!\n");
return 0;
}
while(q != NULL){
node* newNode = (node* ) malloc(sizeof(node));
newNode = getNode(newNode,q->data);
insertNode(head,newNode);
eraseNode(p,q);
q = (node* ) malloc(sizeof(node)); // Allocate again
q = p->link;
}
p->link = NULL;
return 1;
}