( 欢迎加入十月面试题集训组,参与讨论&解题:193308452)
自发表上一篇文章至今(事实上,上篇文章更新了近3个月之久),blog已经停了3个多月,而在那之前,自开博以来的21个月每月都不曾断过。正如上一篇文章支持向量机通俗导论(理解SVM的三层境界)末尾所述:”额,blog许久未有更新了,因为最近实在忙,无暇顾及blog。“与此同时,工作之余,也一直在闲心研究数据挖掘:"神经网络将可能作为Top 10 Algorithms in Data Mining之番外篇第1篇,同时,k-最近邻法(k-nearest neighbor,kNN)算法谈到kd树将可能作为本系列第三篇。这是此系列接下来要写的两个算法,刚好项目中也要用到KD树“。
但很显然,若要等到下一篇数据挖掘系列的文章时,说不定要到年底去了,而最近的这段时间,9月、10月,正是各种校招/笔试/面试火热进行的时节,自己则希望能帮助到这些找工作的朋友,故此,怎能无动于衷,于是,3个多月后,blog今天更新了。
再者,虽然如我的这条微博:http://weibo.com/1580904460/yzs72mmFZ所述,blog自10年10月开通至11年10月,一年的时间内整理了300多道面试题(这300道题全部集锦在此文中第一部分:http://blog.csdn.net/v_july_v/article/details/6543438)。但毕竟那些题已经是前年或去年的了,笔试面试题虽然每年类型变化不大,但毕竟它年年推陈出新,存着就有其合理性。
OK,以下是整理自8月下旬至10月份内的各大公司的笔试面试三十题(注:所有题目基本上全部为软件开发方向,题目来源:网络收集),相信一定能给正在参加各种校招的诸多朋友多少帮助,学习参考或借鉴(如果你手头上有好的笔试/面试题,欢迎通过微博私信:http://weibo.com/julyweibo,或邮箱:[email protected]发给我,或者干脆直接评论在本文下;同时,若你对以下任何一题有任何看法.想法.思路或建议,欢迎留言评论,大家一起讨论,共同享受思考的乐趣,谢谢)。
9月11日, 京东:
谈谈你对面向对象编程的认识
struct rect
{
// axis alignment assumed
// bottom left is (x[0],y[0]), top right is (x[1],y[1])
double x [2];
double y [2];
};
template T const& min (T const& x, T const& y) { return x T const& max (T const& x, T const& y) { return x>y ? x : y; }
// return type changed to handle non-integer rects
double area (rect const& a, rect const& b)
{
// perfectly adjacent rects are considered having an intersection of 0 area
double const dx = min(a.x[1],b.x[1]) - max(a.x[0],b.x[0]);
double const dy = min(a.y[1],b.y[1]) - max(a.y[0],b.y[0]);
return dx>=0&&dy>=0 ? dx*dy : -1;
}
下面是一个简短的证明。4**9 的笔试题,比较简单:
1.求链表的倒数第二个节点
2.有一个整数数组,求数组中第二大的数
template
Comparable maxprod( const vector&v)
{
int i;
Comparable maxProduct = 1;
Comparable minProduct = 1;
Comparable maxCurrent = 1;
Comparable minCurrent = 1;
//Comparable t;
for( i=0; i< v.size() ;i++)
{
maxCurrent *= v[i];
minCurrent *= v[i];
if(maxCurrent > maxProduct)
maxProduct = maxCurrent;
if(minCurrent > maxProduct)
maxProduct = minCurrent;
if(maxCurrent < minProduct)
minProduct = maxCurrent;
if(minCurrent < minProduct)
minProduct = minCurrent;
if(minCurrent > maxCurrent)
swap(maxCurrent,minCurrent);
if(maxCurrent<1)
maxCurrent = 1;
//if(minCurrent>1)
// minCurrent =1;
}
return maxProduct;
}
解法二、/*
给定一个整数数组,有正有负数,0,正数组成,数组下标从1算起
求最大连续子序列乘积,并输出这个序列,如果最大子序列乘积为负数,那么就输出-1
用Max[i]表示以a[i]结尾乘积最大的连续子序列
用Min[i]表示以a[i]结尾乘积最小的连续子序列 因为有复数,所以保存这个是必须的
*/
void longest_multiple(int *a,int n){
int *Min=new int[n+1]();
int *Max=new int[n+1]();
int *p=new int[n+1]();
//初始化
for(int i=0;i<=n;i++){
p[i]=-1;
}
Min[1]=a[1];
Max[1]=a[1];
int max_val=Max[1];
for(int i=2;i<=n;i++){
Max[i]=max(Max[i-1]*a[i],Min[i-1]*a[i],a[i]);
Min[i]=min(Max[i-1]*a[i],Min[i-1]*a[i],a[i]);
if(max_val
变种Q为0
说明数组中至少有两个0,那么N-1个数的乘积只能为0,返回0;
Q为正数
返回Q,因为如果以0替换此时AN-1中的任一个数,所得到的PN-1为0,必然小于Q;
Q为负数
如果以0替换此时AN-1中的任一个数,所得到的PN-1为0,大于Q,乘积最大值为0。
2. P为负数
根据“负负得正”的乘法性质,自然想到从N个整数中去掉一个负数,使得PN-1为一个正数。而要使这个正数最大,这个被去掉的负数的绝对值必须是数组中最小的。我们只需要扫描一遍数组,把绝对值最小的负数给去掉就可以了。
3. P为正数
类似地,如果数组中存在正数值,那么应该去掉最小的正数值,否则去掉绝对值最大的负数值。上面的解法采用了直接求N个整数的乘积P,进而判断P的正负性的办法,但是直接求乘积在编译环境下往往会有溢出的危险(这也就是本题要求不使用除法的潜在用意),事实上可做一个小的转变,不需要直接求乘积,而是求出数组中正数(+)、负数(-)和0的个数,从而判断P的正负性,其余部分与以上面的解法相同。
union{
int i;
unsigned char ch[2];
}Student;
int main()
{
Student student;
student.i=0x1420;
printf("%d %d",student.ch[0],student.ch[1]);
return 0;
}
输出结果为?(答案:32 20)//假设str已经有序,from 一直很安静
void perm(char *str, int size, int resPos)
{
if(resPos == size)
print(result);
else
{
for(int i = 0; i < size; ++i)
{
result[resPos] = str[i];
perm(str, size, resPos + 1);
}
}
}
void fun()
{
unsigned int a = 2013;
int b = -2;
int c = 0;
while (a + b > 0)
{
a = a + b;
c++;
}
printf("%d", c);
}
问:最后程序输出是多少?点评:此题有陷阱,答题需谨慎!2.1 // 采用两两比较的思路(目前没想到更好的)
if (a <= b) {
if (b <= c)
return b;
else {
if (a <=c)
return c;
else
return a;
}
}
else {
if (a <= c)
return a;
else {
if (b <= c)
return c;
else
return b;
}
}
最坏情况下的比较次数:3 (次)//void * memmove ( void * destination, const void * source, size_t num );)
//是的标准函数,其作用是把从source开始的num个字符拷贝到destination。
//最简单的方法是直接复制,但是由于它们可能存在内存的重叠区,因此可能覆盖了原有数据。
//比如当source+count>=dest&&source= (source + count))
{
//正向拷贝
//copy from lower addresses to higher addresses
while (count --)
*dest++ = *source++;
}
else
{
//反向拷贝
//copy from higher addresses to lower addresses
dest += count - 1;
source += count - 1;
while (count--)
*dest-- = *source--;
}
return ret;
}
更多,还可以参见此文第三节节末:http://blog.csdn.net/v_july_v/article/details/6417600,或此文:http://www.360doc.com/content/11/0317/09/6329704_101869559.shtml。 本blog算法群第25群Algorithms_25:173594179;高级C/C++程序员群:125706194;上海程序员联盟群:236869186。
updated
学编程别无他法,多练,准备面试别无他法,多coding,一切,别无他法,多练。欢迎读者朋友们跟我一起思考.做下面这些笔试面试题,show me the code! (对于经验证确定为好的答案,我会编辑自本文之中,且每一题的答案,根据作者要求,除注明代码作者之外,或注明微博昵称,或个人主页及其它联系方式)。
最后,十月底,我会在本文评论下挑选出20位朋友免费赠送 十五个经典算法研究的 WORD文档,作为回馈。与此同时,你在下面一系列笔试面试题目当中,任意挑选N(N>3)题,show出你的思路和代码后「参与的方式为:你除了可以直接评论在本文之下,你也可以通过邮件:[email protected]或私信:http://weibo.com/julyweibo,发给我,且无任何语言限制,写完代码之后,我可能还会问少数几个问题」,经过斟选,代码水平高且合适的我会非常乐意代为介绍和推荐给本人在各大公司的朋友们:http://weibo.com/1580904460/yFlqCASTn。甚者,任何其它合理要求,只要我能做到的,最后都可以跟我提。
#include
#include
#include
int main()
{
char *str1 = "ab23bd2gfhhhr";
int len = strlen(str1);
int i=0,j,count=0;
char *p = (char *)malloc(sizeof(char)*(len+1));
loop:if(i
/*
所有整数都不同 偷懒用set当堆使用
空间复杂度O(k) 用了一个堆 至多有2k个元素 一个队列 至多有k个元素
因为A的值会改变所以用队列保存之前的旧的值
时间复杂度O(nlogk)
*/
void sort(int *A,int n,int k) {
set heap;
queue q;
// k << n
for (int i = 1; i < k; ++i) {
heap.insert(A[i - 1]);
}
// 不算弹出的 维护堆里面是A[i - k] .. A[i + k]
for (int i = 0; i < n; ++i) {
if (i - 1 >= k) {
// 试图删除 A[i - 1 - k]
set::iterator t = heap.find(q.front());
if (t != heap.end()) {
heap.erase(t);
}
q.pop();
}
if (i + k < n) {
heap.insert(A[i + k]);
}
q.push(A[i]);
A[i] = *heap.begin();
heap.erase(heap.begin());
}
}
void movechar(char *s) {
if (s == 0) {
return;
}
int star = 0;
for (end = s; *end;++end) {
if (*end == '*') {
++star;
}
}
//注意空串
for (t = end;star;--end) {
if (*end != '*') {
*t-- = *end;
}
//别越界
if (end == s) {
break;
}
}
for (;star;--star,--t) {
*t = '*';
}
}
list *copyList(list *head) {
list *temp;
// 复制自身next 1 1' 2 2' 3 3'...
for (temp = head;temp;) {
list *other;
other = (list*) malloc(sizeof(list)); // other = new list;
other->data = temp->data;
other->next = temp->next;
temp->next = other;
temp = other->next;
}
// 复制middle
for (temp = head; temp; temp = temp->next->next) {
temp->next->middle = temp->middle->next;
}
//拆
list *otherhead = 0, *othertail = 0, *tail = 0;
for (temp = head; temp; ) {
if (tail == 0) {
tail = temp;
}
else {
tail->next = temp;
tail = temp;
}
temp = temp->next;
if (othertail == 0) {
otherhead = othertail = temp;
}
else {
othertail->next = temp;
othertail = temp;
}
temp = temp->next;
}
//2个if同真假
if (tail) {
tail->next = 0;
}
if (othertail) {
othertail->next = 0;
}
return otherhead;
}
void print(int n, vector &answer) {
printf("%d=",n);
for (int i = 0; i < answer.size(); ++i) {
if (i) {
putchar('+');
}
printf("%d",answer[i]);
}
puts("");
}
void getSum(int n,int now,vector &answer) {
// n must > 0
if (now == n) {
print(n, answer);
return;
}
for (int i = 1; i + now <= n; ++i) {
answer.push_back(i);
getSum(n, now + i, answer);
answer.pop_back();
}
}
// 1/4 3/4的概率返回0和1
int fun2() {
return (fun() == fun())?0:1;
}
// 0.3 0.7的概率返回0,1
int fun3() {
for (;;) {
int x = (fun() << 3) | (fun() << 2) | (fun() << 1) | fun();
if ( x < 3) {
return 0;
}
if ( x < 10) {
return 1;
}
}
// never get here
return -1;
}
int miniabs(int *a,int n) {
// n <= 0 返回 -1
int left = 0, right = n - 1, mid, maxnegIndex = -1, minposIndex = -1;
while (left <= right) {
mid = (left + right) >> 1;
if (a[mid] < 0) {
maxnegIndex = mid;
left = mid + 1;
}
else if (a[mid] > 0) {
minposIndex = mid;
right = mid - 1;
}
}
if (maxnegIndex < 0) {
return (minposIndex < 0)?(-1):a[minposIndex];
}
if (minposIndex < 0) {
return -a[maxnegIndex];
}
return (a[minposIndex] < -a[maxnegIndex])?a[minposIndex]:-a[maxnegIndex];
}
bool searchMatrix(vector > &matrix, int target) {
int m = matrix.size();
if (m == 0) {
return false;
}
int n = matrix[0].size();
int i , j;
for (i = 0,j = n - 1;(i < m) && (j >= 0);) {
if (matrix[i][j] == target) {
return true;
}
if (matrix[i][j] > target) {
--j;
}
else {
++i;
}
}
return false;
}
ListNode *reverseKGroup(ListNode *head) {
ListNode *remain = head, *tail = 0;
for (head = 0;remain && remain->next;) {
Node *p1 = remain->next;
Node *p2 = p1->next;
p1->next = remain;
if (tail) {
tail->next = p1;
}
else {
head = p1;
}
tail = remain;
remain = p2;
}
if (tail) {
tail->next = remain;
}
if (!head) {
head = remain;
}
return head;
}
double maxSum(double *f, int len) {
if (len <= 0) {
return 0;
}
double maxEnd = f[0], maxAns = f[0];
for (int i = 1; i < len; ++i) {
maxAns = max(maxAns , maxEnd = max(f[i] + maxEnd, f[i]));
}
return maxAns;
}
double maxMultiply(double *f, int len) {
if (len <= 0) {
return 0;
}
double maxEnd = f[0], minEnd = f[0], maxAns = f[0], minAns = f[0];
for (int i = 1; i < len; ++i) {
double temp1 = maxEnd * f[i], temp2 = minEnd * f[i];
maxAns = max(maxAns , maxEnd = max(max(temp1, temp2) , f[i]));
minAns = min(minAns, minEnd = min(min(temp1,temp2), f[i]));
}
return maxAns;
}
char* trim(char *s) {
if (s == 0) {
return 0;
}
for (;isspace(*s);++s)
;
char *end;
for (end = s;*end;++end)
;
if (end != s) {
for (--end;isspace(*end);--end)
;
*(end + 1) = 0;
}
return s;
}
char* TrimandDelete(char *s) {
if (s == 0) {
return 0;
}
char *now = s, *t;
for (t = s; *t; ++t) {
if (isspace(*t)) {
if ((t == s) || (!isspace(*(t - 1)))) {
*now++ = *t;
}
}
else {
*now++=*t;
}
}
*now = 0;
return trim(s);
}
#include
#include
using namespace std;
void print(vector &vec){
for(vector::iterator it = vec.begin(); it != vec.end(); ++it){
cout << *it << " ";
}
cout << endl;
}
void search(int dest, int min, vector &vec){
if(dest == 0){
print(vec);
return;
}
if(dest < min)
return;
for(int i = min; i <= dest; ++i){
vec.push_back(i);
search(dest - i, i, vec);
vec.pop_back();
}
}
int main(){
vector vec;
search(10, 1, vec);
return 0;
}
void __stdcall StripAndZip(char *str)
{
char *fast=str,*slow=str;
while(*fast != '\0')
{
while(*fast == ' ')
fast++;
*slow++=*fast++;
//restore the position of "fast":tmp
char *tmp=fast;
while(*fast == ' '&& *fast!='\0')
{
fast++;
}
//if the *fast has already become the '\0',then trim all the trailing space
if(*fast == '\0')
{
*slow='\0';
break;
}
if((ptrdiff_t)(fast-tmp) == 1) //just contains one space,so the *slow should copy that
{
*slow++=' ';
*slow++=*fast++;
}
else if((ptrdiff_t)(fast-tmp) >= 1) //more than one space will become only one
{
*slow++=' ';
}
}
}
#include
using namespace std;
void print(int * arr,int n)
{
for (int i=n-1;i>=0;i--)
cout<<*(arr+i)<<" ";
cout<root[i])
{
int tmp=root[i];
root[i]=root[j];
root[j]=tmp;
}
else
break;
i=j;
}
}
void sumOfArr(int * arr1,int * arr2, int * tmp, int n)
{
for (int i=0;i
define Min_k 6 //要求的数字个数,在这里假设为6
void MaoPao(int *array)//用最简单的冒泡排序对辅助数组进行排序,可以用其他的方法
{
for (int i=0;iarray[j+1])
{
array[j]=array[j]^array[j+1];
array[j+1]=array[j+1]^array[j];
array[j]=array[j]^array[j+1];
}
}
}
}
void Binsert(int *array) //对辅助的数组进行插入排序
{
int mid,low=0,high=Min_k-2; //最后一个和前(k-1)数字的比较
while (low<=high) //因为是顺序数组,所以直接二分查找,用的时间比较少
{
mid=(low+high)/2;
if (array[Min_k-1]>array[mid])
{
low=mid+1;
}
else
{
high=mid-1;
}
}
int temp=array[Min_k-1];
for (int i=Min_k-2;i>=high+1;i--)
{
array[i+1]=array[i];
}
array[high+1]=temp;
}
void Min_Array(int *array,int n) //k是要求的最小的k个数字,n是数组的大小
{
int assist[Min_k];
for (int i=0;i
void fun()
{
unsigned int a = 2013;
int b = -2;
int c = 0;
while (a + b > 0)
{
a = a + b;
c++;
}
printf("%d", c);
}
#include
#include
void str_sort(char a[], int size)
{
int i, j, t;
for(j = 0; j < size; j++) /*第j趟比较*/
{
for(i = 0; i < size - j; i++) /*第j趟要比较的次数(9 - j)次*/
if((int)a[i] > (int)a[i+1])
{
t = a[i]; /*将较大的数往后移*/
a[i] = a[i+1];
a[i+1] = t; /*最后肯定会冒出一个最大的数,并存储在a[i]中*/
}
}
}
void isbrotherstr(char *str1, char *str2[], int num)
{
char str_temp[20];
str_sort(str1, strlen(str1) - 1);
while(num)
{
if (strlen(str1) != strlen(*str2)) /* 长度不等的话就不用比较了 */
{
str2++;
num--;
}
else
{
strcpy(str_temp, *str2);
str_sort(str_temp, strlen(*str2) - 1);
if (strcmp(str1, str_temp) == 0)
{
printf("%s ", *str2);
}
str2++;
num--;
}
}
}
int main(void)
{
char str1[] = "armyb";
char *str2[] = {"maryb", "marby", "mabry", "amrby", "vvdbgr"};
int num = sizeof(str2) / sizeof(char *);
isbrotherstr(str1, str2, num);
return 0;
}
2.1 // 采用两两比较的思路(目前没想到更好的)
if (a <= b) {
if (b <= c)
return b;
else {
if (a <=c)
return c;
else
return a;
}
}
else {
if (a <= c)
return a;
else {
if (b <= c)
return c;
else
return b;
}
}
public String sortWithKey (String key, String s) {
if (key == null || s == null)
return null;
StringBuffer sbuf = new StringBuffer();
int[] hashmap = new int[26];
for (int i = 0; i < 26; i++)
hashmap[i] = 0;
char[] sChar = s.toCharArray();
for (int i = 0; i < sChar.length; i++)
hashmap[sChar[i]-'a']++;
char[] keyChar = key.toCharArray();
for (int i = 0; i < keyChar.length; i++) {
while (hashmap[keyChar[i]-'a'] > 0) {
sbuf.append(keyChar[i]);
hashmap[keyChar[i]-'a']--;
}
}
for (int i = 0; i < 26; i++)
while (hashmap[i] > 0) {
sbuf.append((char)('a'+i));
hashmap[i]--;
}
return sbuf.toString();
}
copyright@宇智波鼬,2012.10.03
#include
#include
#include
#include
using namespace std;
typedef struct Node
{
char data;
struct Node *next;
}Node,*LinkList;
void create_list(const char *str,LinkList *head)
{//the head node contain key word
int len=strlen(str);
int i;
Node *temp=NULL;
Node *p=NULL;
for(i=0;idata=str[i];
p->next=NULL;
if((*head)==NULL)
{
*head=p;
temp=p;
}
else
{
temp->next=p;
temp=p;
}
}
}
void inverse_list(LinkList *head)
{//inverse the link list
Node *pre=NULL;
Node *cur=*head;
Node *next=NULL;
while(cur&&cur->next)
{
if(pre==NULL)
*head=cur->next;
else
pre->next=cur->next;
pre=cur;
next=cur->next->next;
cur->next->next=cur;
cur->next=next;
cur=next;
}
}
void print_list(LinkList head)
{//print link list
//....
}
void delete_list(LinkList *head)
{//delete link list
//....
}
int main()
{
char str[]="hijklmn";
LinkList head=NULL;
create_list(str,&head);
print_list(head);
inverse_list(&head);
print_list(head);
delete_list(&head);
system("pause");
return 0;
}
void travle_tree(pTree pRoot)
{
pNODE pNew;
pNODE pNode;
QUEUEPRT pQ = (QUEUEPRT)malloc(sizeof(QUEUE));
pNODE ptemp_node = (pNODE)malloc(sizeof(NODE));
ptemp_node->ptree = pRoot;
pNode = ptemp_node;
if (pRoot == NULL)
{
return ;
}
pQ->front = pQ->rear = pRoot;
while (pQ->front->firstChild != NULL || pQ->front->sibling != NULL ||ptemp_node != NULL)
{
printf("%c ", ptemp_node->ptree->ch);
if (ptemp_node->ptree->firstChild != NULL)
{
pNew = (pNODE)malloc(sizeof(NODE));
pNew->ptree = ptemp_node->ptree->firstChild;
pNode->pNext = pNew;
pNode = pNode->pNext;
pQ->rear = pNew->ptree;
pNode->pNext = NULL;
}
if (ptemp_node->ptree->sibling != NULL)
{
pNew = (pNODE)malloc(sizeof(NODE));
pNew->ptree = ptemp_node->ptree->sibling;
pNode->pNext = pNew;
pNode = pNode->pNext;
pQ->rear = pNew->ptree;
pNode->pNext = NULL;
}
pQ->front = ptemp_node->ptree;
ptemp_node = ptemp_node->pNext;
}
}