原文地址:http://m.blog.csdn.net/blog/panfengyun12345/12618453
//copyright@July 2013/9/24 void* memcpy(void *dst, const void *src, size_t count) { //安全检查 assert( (dst != NULL) && (src != NULL) ); unsigned char *pdst = (unsigned char *)dst; const unsigned char *psrc = (const unsigned char *)src; //防止内存重复 assert(!(psrc<=pdst && pdst<psrc+count)); assert(!(pdst<=psrc && psrc<pdst+count)); while(count--) { *pdst = *psrc; pdst++; psrc++; } return dst; }
struct node { int elem; node* next; };
9月11日, 京东:
谈谈你对面向对象编程的认识
struct Node{ Node* parent; Node* firstChild; // 孩子节点 Node* sibling; // 兄弟节点 }
typedef struct list { int data; //数据字段 list *middle; //指向链表中某任意位置元素(可指向自己)的指针 list *next;//指向链表下一元素 } list;
var tt = 'aa'; function test() { alert(tt); var tt = 'dd'; alert(tt); } test();
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 <typename T> T const& min (T const& x, T const& y) { return x<y ? x : y; } template <typename T> 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 <typename Comparable> Comparable maxprod( const vector<Comparable>&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<Max[i]) max_val=Max[i]; } if(max_val<0) printf("%d",-1); else printf("%d",max_val); //内存释放 delete [] Max; delete [] Min; }
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; }
//假设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); }
#include <STDIO.H> #include <WINDOWS.H> int Friends(int n, int m , int* r[]); int main(int argc,char** argv) { int r[5][2] = {{1,2},{4,3},{6,5},{7,8},{7,9}}; printf("有%d个朋友圈。\n",Friends(0,5,(int**)r)); return 0; } int Friends(int n, int m, int* r[]) // 注意这里的参数很奇葩 { int *p = (int*)malloc(sizeof(int)*m*3); memset(p,0,sizeof(int)*m*3); int i = 0; int iCount = 0; int j = 0; int * q = (int*)r; // 这里很巧妙 将二维指针 强转为一维指针 for (i=0;i<m;++i) { for (j=0;j<2;++j) { p[i*3+j]=q[i*2+j]; // 注意这里二维数组向一维数组的转换 } p[i*3+j] = 0; } bool bFlag = false; for (i=0;i<m;++i) { bFlag = false; if (p[i*3+2]==1) { bFlag = true; } p[i*3+2] = 1; for (j=0;j<m;++j) { if (i==j) { continue; } if (p[i*3]==p[j*3] || p[i*3] == p[j*3+1] || p[i*3+1] == p[j*3+0] || p[i*3+1] == p[j*3+1]) { if (p[j*3+2]==1) { bFlag = true; } p[j*3+2] = 1; } } if (!bFlag) { ++iCount; } } free(p); return iCount; }
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; } }
//void * memmove ( void * destination, const void * source, size_t num );) //是<string.h>的标准函数,其作用是把从source开始的num个字符拷贝到destination。 //最简单的方法是直接复制,但是由于它们可能存在内存的重叠区,因此可能覆盖了原有数据。 //比如当source+count>=dest&&source<dest时,dest可能覆盖了原有source的数据。 //解决办法是从后往前拷贝。 //对于其它情况,则从前往后拷贝。 void* memmove(void* dest, void* source, size_t count) { void* ret = dest; if (dest <= source || dest >= (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; }
10月10日人人网面试题
第一面:
1、(1)++i 和 i++,那个效率高?
(2)++++i,i++++,哪个是合法的?
(3)实现int型的++i 和 i++操作。
2、一段程序,求输出。(考察静态变量和模版类)
int g = 0; template<typename T> class B { public: int static fun() { static int value = ++g; return value; } }; int main() { cout << B<int>::fun() << endl; cout << B<char>::fun() << endl; cout << B<float>::fun() << endl; cout << B<int>::fun() << endl; cout << B<long>::fun() << endl; return 0; }
//copyright @wumuzi520 //从n个数中选取m个数的组合数 void Combination(int arr[], int nLen, int m, int out[], int outLen) { if(m == 0) { for (int j = 0; j < outLen; j++) { cout << out[j] << "\t"; } cout << endl; return; } for (int i = nLen; i >= m; --i) //从后往前依次选定一个 { out[m-1] = arr[i-1]; //选定一个后 Combination(arr,i-1,m-1,out,outLen); // 从前i-1个里面选取m-1个进行递归 } } void PrintCombination(int arr[], int nLen, int m) { int* out = new int[m]; Combination(arr,nLen,m,out,m); delete [] out; }
static void Main(string[] args) { double k = 5; double n = 2, m = k; while (n != m) { m = k / n; n = (m + n) / 2; } }
西芹_new<[email protected]> 0:55:40 // 10_15.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> using namespace std; #define N 5 int map[5][5]={ {2,0,8,0,2}, {0,0,0,0,0}, {0,3,2,0,0}, {0,0,0,0,0}, {2,0,8,0,2}}; int sumMax=0; int p1x=0; int p1y=0; int p2x=0; int p2y=0; int curMax=0; void dfs( int index){ if( index == 2*N-2){ if( curMax>sumMax) sumMax = curMax; return; } if( !(p1x==0 && p1y==0) && !(p2x==N-1 && p2y==N-1)) { if( p1x>= p2x && p1y >= p2y ) return; } //right right if( p1x+1<N && p2x+1<N ){ p1x++;p2x++; int sum = map[p1x][p1y]+map[p2x][p2y]; curMax += sum; dfs(index+1); curMax -= sum; p1x--;p2x--; } //down down if( p1y+1<N && p2y+1<N ){ p1y++;p2y++; int sum = map[p1x][p1y]+map[p2x][p2y]; curMax += sum; dfs(index+1); curMax -= sum; p1y--;p2y--; } //rd if( p1x+1<N && p2y+1<N ) { p1x++;p2y++; int sum = map[p1x][p1y]+map[p2x][p2y]; curMax += sum; dfs(index+1); curMax -= sum; p1x--;p2y--; } //dr if( p1y+1<N && p2x+1<N ) { p1y++;p2x++; int sum = map[p1x][p1y]+map[p2x][p2y]; curMax += sum; dfs(index+1); curMax -= sum; p1y--;p2x--; } } int _tmain(int argc, _TCHAR* argv[]) { curMax = map[0][0]; dfs(0); cout <<sumMax-map[N-1][N-1]<<endl; return 0; }
10月15日,网新恒天笔试题
1.不要使用库函数,写出void *memcpy(void *dst, const void *src, size_t count),其中dst是目标地址,src是源地址。
点评:下面是nwpulei写的代码:
void* memcpy(void *dst, const void *src, size_t count) { assert(dst != NULL); assert(src != NULL); unsigned char *pdst = (unsigned char *)dst; const unsigned char *psrc = (const unsigned char *)src; assert(!(psrc<=pdst && pdst<psrc+count)); assert(!(pdst<=psrc && psrc<pdst+count)); while(count--) { *pdst = *psrc; pdst++; psrc++; } return dst; }
链接:http://blog.csdn.net/nwpulei/article/details/8090136。
2.给定一个字符串,统计一下哪个字符出现次数最大。
3.我们不知道Object类型的变量里面会出现什么内容,请写个函数把Object类型转换为int类型。
Int CalculateStringDistance(string strA, int pABegin, int pAEnd, string strB, int pBBegin, int pBEnd) { if(pABegin > pAEnd) { if(pBBegin > pBEnd) return 0; else return pBEnd – pBBegin + 1; } if(pBBegin > pBEnd) { if(pABegin > pAEnd) return 0; else return pAEnd – pABegin + 1; } if(strA[pABegin] == strB[pBBegin]) { return CalculateStringDistance(strA, pABegin + 1, pAEnd, strB, pBBegin + 1, pBEnd); } else { int t1 = CalculateStringDistance(strA, pABegin, pAEnd, strB, pBBegin + 1, pBEnd); int t2 = CalculateStringDistance(strA, pABegin + 1, pAEnd, strB,pBBegin, pBEnd); int t3 = CalculateStringDistance(strA, pABegin + 1, pAEnd, strB,pBBegin + 1, pBEnd); return minValue(t1,t2,t3) + 1; } }
上面的递归程序,有什么地方需要改进呢?在递归的过程中,有些数据被重复计算了。比如,如果开始我们调用CalculateStringDistance(strA,1, 2, strB, 1, 2),下图是部分展开的递归调用。
可以看到,圈中的两个子问题被重复计算了。为了避免这种不必要的重复计算,可以把子问题计算后的解存储起来。如何修改递归程序呢?还是DP!请看此链接:http://www.cnblogs.com/yujunyong/articles/2004724.html。
3、此外,关于这个“编辑距离”问题的应用:搜索引擎关键字查询中拼写错误的提示,可以看下这篇文章:http://www.ruanyifeng.com/blog/2012/10/spelling_corrector.html。「关于什么是“编辑距离”:一个快速、高效的Levenshtein算法实现,这个是计算两个字符串的算法,Levenshtein距离又称为“编辑距离”,是指两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。当然,次数越小越相似。这里有一个BT树的数据结构,挺有意思的:http://blog.notdot.net/2007/4/Damn-Cool-Algorithms-Part-1-BK-Trees」
最后,Lucene中也有这个算法的实现(我想,一般的搜索引擎一般都应该会有此项拼写错误检查功能的实现):http://www.bjwilly.com/archives/395.html。
4、扩展:面试官还可以继续问下去:那么,请问,如何设计一个比较两篇文章相似性的算法?(这个问题的讨论可以看看这里:http://t.cn/zl82CAH)
10月28日,微软三面题「顺祝,老妈明天生日快乐!」:
找一个点集中与给定点距离最近的点,同时,给定的二维点集都是固定的,查询可能有很多次,时间复杂度O(n)无法接受,请设计数据结构和相应的算法。
类似于@陈利人:附近地点搜索,就是搜索用户附近有哪些地点。随着GPS和带有GPS功能的移动设备的普及,附近地点搜索也变得炙手可热。在庞大的地理数 据库中搜索地点,索引是很重要的。但是,我们的需求是搜索附近地点,例如,坐标(39.91, 116.37)附近500米内有什么餐馆,那么让你来设计,该怎么做?
点评:R树「从B树、B+树、B*树谈到R 树」还是KD树「从K近邻算法、距离度量谈到KD树、SIFT+BBF算法」?