Interview

来源:互联网 发布:初学java看什么书好 编辑:程序博客网 时间:2024/05/01 12:17
<pre name="code" class="cpp"><span style="font-family: Arial, Helvetica, sans-serif;">1,DSAA,寻找第K小的数</span>

#include <iostream>using namespace std;int binSearchKth(int arr[], int x, int y, size_t k){int low = x, high = y;size_t cnt = 0;int cur = arr[low];while (low < high){while (cur < arr[high] && low < high){high--;}arr[low] = arr[high];while (cur >= arr[low] && low < high){low++;}//cnt++;arr[high] = arr[low];}arr[low] = cur;for (int i = x; i <= y; ++i){if (arr[i] <= cur)++cnt;cout << arr[i] << endl;}cout << low << '\t' << high << '\t' << cnt << endl;if (cnt == k)return cur;else if (cnt > k)return binSearchKth(arr, x, low - 1, k);elsereturn binSearchKth(arr, low + 1, y, k - cnt);}int main(){int arr[7] = { 7, 5, -6, 3, 2, 4, 6 };//int arr[7] = { 1,2,3,4,5,6,7};int k = 1;cout << binSearchKth(arr, 0, 6, 8 - k);}

2.二分查找

#include <iostream>using namespace std;int binSearch(int arr[], int low, int high, int k){while (low <= high){int mid = (low + high) >> 1;if (arr[mid] == k)return mid;else if (arr[mid] > k){high = mid - 1;//binSearch(arr, low, mid - 1, k);}elselow = mid + 1;    //binSearch(arr, mid + 1, high, k);}}int main(){int arr[6] = { 1, 2, 3, 4, 5, 6 };//int arr[7] = { 1,2,3,4,5,6,7};int k = 1;cout << binSearch(arr, 0, 6, 4) << endl;}

3.分治实现的求最大子序列和的算法

优化前的算法

#include <iostream>using namespace std;int binGetMax(int arr[], int low, int high, int& start, int& end){if (low >= high){start = end = low;return arr[low];}int mid = (low + high) >> 1;int max = -0x7ffffff;int lstart = low, lend = mid - 1, rstart = mid + 1, rend = high;int leftRet = binGetMax(arr, low, mid - 1, lstart, lend);int rightRet = binGetMax(arr, mid + 1, high, rstart, rend);int leftmax = 0;for (int i = lstart; i < mid; ++i){leftmax += arr[i];}int rightmax = 0;for (int i = mid + 1; i <= rend; ++i){rightmax += arr[i];}if (leftRet > rightRet){max = leftRet;start = lstart; end = lend;}else{max = rightRet;start = rstart; end = rend;}if (rightmax + arr[mid] > max){max = rightmax + arr[mid];start = mid; end = rend;}if (leftmax + arr[mid] > max){max = leftmax + arr[mid];start = lstart; end = mid;}if (leftmax + rightmax + arr[mid] > max){max = leftmax + rightmax + arr[mid];start = lstart; end = rend;}return max;}int main(){int arr[7] = { -1,-2,-3,-4,-5,-6,-7};int len = (sizeof arr) / sizeof(arr[0]);int start = 0, end = len - 1;///////////////////////////////// attention 下面两个cout不能合并为一句话,这个跟编译器相关cout << binGetMax(arr, 0, end, start, end) << endl;cout << "start" << start << '\t' << "end" << end << endl;}

优化后的算法


#include <iostream>using namespace std;int binGetMax(int arr[], int low, int high, int& start, int& end){if (low == high){start = end = low;return arr[low];}int mid = (low + high) >> 1;int max = -0x7ffffff;int lstart = low, lend = mid, rstart = mid + 1, rend = high;int leftRet = binGetMax(arr, low, mid, lstart, lend);int rightRet = binGetMax(arr, mid + 1, high, rstart, rend);int leftmax = 0;for (int i = lstart; i <= mid; ++i){leftmax += arr[i];}int rightmax = 0;for (int i = mid + 1; i <= rend; ++i){rightmax += arr[i];}if (leftRet > rightRet){max = leftRet;start = lstart; end = lend;}else{max = rightRet;start = rstart; end = rend;}if (leftmax + rightmax > max){max = leftmax + rightmax;start = lstart; end = rend;}return max;}int main(){int arr[9] = { 5, -1, -2, -1, 6, -2, -10, -10, 8};int len = (sizeof arr) / sizeof(arr[0]);int start = 0, end = len - 1;///////////////////////////////// attention 下面两个cout不能合并为一句话,这个跟编译器相关cout << binGetMax(arr, 0, end, start, end) << endl;cout << "start" << start << '\t' << "end" << end << endl;}

书上的算法:

#include <iostream>using namespace std;static int MaxSubSum(const int A[], int left, int right){int maxLeftSum, maxRightSum;int maxleftBorderSum, maxRightBorderSum;int leftBorderSum, rightBorderSum;int center;if (left == right){if (A[left] > 0)return A[left];elsereturn 0;}center = (left + right) >> 1;maxLeftSum = MaxSubSum(A, left, center);maxRightSum = MaxSubSum(A, center + 1, right);maxleftBorderSum = 0; leftBorderSum = 0;for (int i = center; i >= left; i--){leftBorderSum += A[i];if (leftBorderSum > maxleftBorderSum)maxleftBorderSum = leftBorderSum;}maxRightBorderSum = 0; rightBorderSum = 0;for (int i = center + 1; i <= right; i++){rightBorderSum += A[i];if (rightBorderSum > maxRightBorderSum)maxRightBorderSum = rightBorderSum;}int max = maxLeftSum > maxRightSum ? maxLeftSum : maxRightSum;max = max > maxleftBorderSum + maxRightBorderSum ? max : maxleftBorderSum + maxRightBorderSum;return max;}int main(){int arr[9] = { 5, -1, -2, -1, 6, -2, -10, -10, 8};//int arr[4] = { 1, 2, 3, 4 };int len = (sizeof arr) / sizeof(arr[0]);int start = 0, end = len - 1;///////////////////////////////// attention 下面两个cout不能合并为一句话,这个跟编译器相关cout << MaxSubSum(arr, 0, end) << endl;cout << "start" << start << '\t' << "end" << end << endl;}


4.求最大公约数

#include <iostream>using namespace std;int gcd(int m, int n){if (n == 0)return m;elsereturn gcd(n, m % n);}int main(){int m, n;while (cin >> m >> n){cout << gcd(m, n) << endl;}}

非递归算法

#include <iostream>using namespace std;int gcd(int m, int n){while (n > 0){int tmp = m;m = n;n = tmp % n;}return m;}int main(){int m, n;while (cin >> m >> n){cout << gcd(m, n) << endl;}}

5.快速幂,非递归版本

#include <iostream>using namespace std;int fastPow(int m, int n){int ret = 1;while (n > 0){if ((n & 1) == 1){ret *= m;m *= m;n >>= 1;continue;}m *= m;n >>= 1;}return ret;}int main(){int m, n;while (cin >> m >> n){cout << fastPow(m, n) << endl;}}

递归版本

#include <iostream>using namespace std;int fastPow(int m, int n){int ret = 1;if (n == 0)return 1;if (n == 1)return m;if (n & 1)return m * fastPow(m * m, n >> 1);elsereturn fastPow(m * m, n >> 1);}int main(){int m, n;while (cin >> m >> n){cout << fastPow(m, n) << endl;}}

6.C语言版本的链表

头文件

/* bo2-2.c 单链表线性表(存储结构由c2-2.h定义)的基本操作(12个) */#include <stdio.h>#include<string.h>#include<ctype.h>#include<malloc.h> /* malloc()等 */#include<limits.h> /* INT_MAX等 */#include<stdio.h> /* EOF(=^Z或F6),NULL */#include<stdlib.h> /* atoi() */#include<io.h> /* eof() */#include<math.h> /* floor(),ceil(),abs() */#include<process.h> /* exit() *//* 函数结果状态代码 */#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1/* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */typedef int ElemType;struct LNode{ElemType data;struct LNode *next;};typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */Status InitList(LinkList *L);Status DestroyList(LinkList *L);Status ClearList(LinkList L);Status ListEmpty(LinkList L);int ListLength(LinkList L);Status GetElem(LinkList L, int i, ElemType *e);int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType));Status PriorElem(LinkList L, ElemType cur_e, ElemType *pre_e);Status NextElem(LinkList L, ElemType cur_e, ElemType *next_e);Status ListInsert(LinkList L, int i, ElemType e);Status ListDelete(LinkList L, int i, ElemType *e);Status ListTraverse(LinkList L, void(*vi)(ElemType));
实现文件,注意,初始化和删除链表中的参数为一个指针的指针是必要的,并且这个方法可以近似的代替引用

#include "list.h"//#include "c1.h" Status InitList(LinkList *L) { /* 操作结果:构造一个空的线性表L */   *L=(LinkList)malloc(sizeof(struct LNode)); /* 产生头结点,并使L指向此头结点 */   if(!*L) /* 存储分配失败 */     exit(OVERFLOW);   (*L)->next=NULL; /* 指针域为空 */   return OK; } Status DestroyList(LinkList *L) { /* 初始条件:线性表L已存在。操作结果:销毁线性表L */   LinkList q;   while(*L)   {     q=(*L)->next;     free(*L);     *L=q;   }   return OK; } Status ClearList(LinkList L) /* 不改变L */ { /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */   LinkList p,q;   p=L->next; /* p指向第一个结点 */   while(p) /* 没到表尾 */   {     q=p->next;     free(p);     p=q;   }   L->next=NULL; /* 头结点指针域为空 */   return OK; } Status ListEmpty(LinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */   if(L->next) /* 非空 */     return FALSE;   else     return TRUE; } int ListLength(LinkList L) { /* 初始条件:线性表L已存在。操作结果:返回L中数据元素个数 */   int i=0;   LinkList p=L->next; /* p指向第一个结点 */   while(p) /* 没到表尾 */   {     i++;     p=p->next;   }   return i; } Status GetElem(LinkList L,int i,ElemType *e) /* 算法2.8 */ { /* L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR */   int j=1; /* j为计数器 */   LinkList p=L->next; /* p指向第一个结点 */   while(p&&j<i) /* 顺指针向后查找,直到p指向第i个元素或p为空 */   {     p=p->next;     j++;   }   if(!p||j>i) /* 第i个元素不存在 */     return ERROR;   *e=p->data; /* 取第i个元素 */   return OK; } int LocateElem(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType)) { /* 初始条件: 线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0) */   /* 操作结果: 返回L中第1个与e满足关系compare()的数据元素的位序。 */   /*           若这样的数据元素不存在,则返回值为0 */   int i=0;   LinkList p=L->next;   while(p)   {     i++;     if(compare(p->data,e)) /* 找到这样的数据元素 */       return i;     p=p->next;   }   return 0; } Status PriorElem(LinkList L,ElemType cur_e,ElemType *pre_e) { /* 初始条件: 线性表L已存在 */   /* 操作结果: 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱, */   /*           返回OK;否则操作失败,pre_e无定义,返回INFEASIBLE */   LinkList q,p=L->next; /* p指向第一个结点 */   while(p->next) /* p所指结点有后继 */   {     q=p->next; /* q为p的后继 */     if(q->data==cur_e)     {       *pre_e=p->data;       return OK;     }     p=q; /* p向后移 */   }   return INFEASIBLE; } Status NextElem(LinkList L,ElemType cur_e,ElemType *next_e) { /* 初始条件:线性表L已存在 */   /* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继, */   /*           返回OK;否则操作失败,next_e无定义,返回INFEASIBLE */   LinkList p=L->next; /* p指向第一个结点 */   while(p->next) /* p所指结点有后继 */   {     if(p->data==cur_e)     {       *next_e=p->next->data;       return OK;     }     p=p->next;   }   return INFEASIBLE; } Status ListInsert(LinkList L,int i,ElemType e) /* 算法2.9。不改变L */ { /* 在带头结点的单链线性表L中第i个位置之前插入元素e */   int j=0;   LinkList p=L,s;   while(p&&j<i-1) /* 寻找第i-1个结点 */   {     p=p->next;     j++;   }   if(!p||j>i-1) /* i小于1或者大于表长 */     return ERROR;   s=(LinkList)malloc(sizeof(struct LNode)); /* 生成新结点 */   s->data=e; /* 插入L中 */   s->next=p->next;   p->next=s;   return OK; } Status ListDelete(LinkList L,int i,ElemType *e) /* 算法2.10。不改变L */ { /* 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值 */   int j=0;   LinkList p=L,q;   while(p->next&&j<i-1) /* 寻找第i个结点,并令p指向其前趋 */   {     p=p->next;     j++;   }   if(!p->next||j>i-1) /* 删除位置不合理 */     return ERROR;   q=p->next; /* 删除并释放结点 */   p->next=q->next;   *e=q->data;   free(q);   return OK; } Status ListTraverse(LinkList L,void(*vi)(ElemType)) /* vi的形参类型为ElemType,与bo2-1.c中相应函数的形参类型ElemType&不同 */ { /* 初始条件:线性表L已存在 */   /* 操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败 */   LinkList p=L->next;   while(p)   {     vi(p->data);     p=p->next;   }   printf("\n");   return OK; }

纯C只能在程序段最前面定义变量,不能再程序段中间定义变量



0 0