分享

几道c/c++笔试题目

 学无涯_思无涯 2013-09-12

1、给一个数组,元素都是整数(有正数也有负数),寻找连续的元素相加之和为最大的序列。

如:1、-2、3、5、-4、6 连续序列3、5、-4、6的和最大。
如元素全为负数,则最大的和为0,即一个也没有选。
/*
array[]     输入数组
n           数组元素个数
            返回最大序列和
*/
int find_max_sum(int array[] , int n)

  1. int find_max_sum(int array[] , int n)    
  2. {    
  3.     int i , max , sum;    
  4.     sum = max = array[0];    
  5.     for(i = 1 ; i < n ; ++i)    
  6.     {    
  7.         if(sum < 0)    
  8.             sum = array[i];    
  9.         else    
  10.             sum += array[i];    
  11.         if(sum > max)    
  12.             max = sum;    
  13.     }    
  14.     if(max < 0)    
  15.         max = 0;    
  16.     return max;    
  17. }    

2、给定一个字符串,求出其最长重复子串

例如:abcdabcd
最长重复子串是 abcd,最长重复子串可以重叠
例如:abcdabcda,这时最长重复子串是 abcda,中间的 a 是被重叠的。

直观的解法是,首先检测长度为 n - 1 的字符串情况,如果不存在重复则检测 n - 2, 一直递减下去,直到 1 。
这种方法的时间复杂度是 O(N * N * N),其中包括三部分,长度纬度、根据长度检测的字符串数目、字符串检测。

改进的方法是利用后缀数组
后缀数组是一种数据结构,对一个字符串生成相应的后缀数组后,然后再排序,排完序依次检测相邻的两个字符串的开头公共部分。
这样的时间复杂度为:生成后缀数组 O(N),排序 O(NlogN*N) 最后面的 N 是因为字符串比较也是 O(N)
依次检测相邻的两个字符串 O(N * N),总的时间复杂度是 O(N^2*logN),优于第一种方法的 O(N^3)

  1. #include <iostream>    
  2. using namespace std;    
  3.     
  4. #define MAXCHAR 5000 //最长处理5000个字符    
  5.     
  6. char c[MAXCHAR], *a[MAXCHAR];    
  7.     
  8. int comlen( char *p, char *q )    
  9. {    
  10.     int i = 0;    
  11.     while( *p && (*p++ == *q++) )    
  12.         ++i;    
  13.     return i;    
  14. }    
  15. int pstrcmp( const void *p1, const void *p2 )    
  16. {    
  17.     return strcmp( *(charconst *)p1, *(charconst*)p2 );    
  18. }    
  19. int main(void)    
  20. {    
  21.     char ch;    
  22.     int  n=0;    
  23.     int  i, temp;    
  24.     int  maxlen=0, maxi=0;    
  25.     printf("Please input your string:\n");    
  26.     n = 0;    
  27.     while( (ch=getchar())!='\n' )    
  28.     {    
  29.         a[n] = &c[n];    
  30.         c[n++] = ch;    
  31.     }    
  32.     c[n]='\0';     // 将数组c中的最后一个元素设为空字符,以终止所有字符串    
  33.     
  34.     qsort( a, n, sizeof(char*), pstrcmp );    
  35.     for(i = 0 ; i < n-1 ; ++i )    
  36.     {    
  37.         temp=comlen( a[i], a[i+1] );    
  38.         if( temp>maxlen )    
  39.         {    
  40.             maxlen=temp;    
  41.             maxi=i;    
  42.         }    
  43.     }    
  44.     printf("%.*s\n",maxlen, a[maxi]);    
  45.     return 0;    
  46. }    

3、字符转换成数字,数字转换成数组

  1. //字符转换成数字,数字转换成字符  
  2. #include<stdio.h>  
  3. void main()  
  4. {  
  5.     int i=0,j=0,x=0,num=0,n=1234;  
  6.     char a[]={'1','2','3','4','\0'};  
  7.     while(a[i])  
  8.     {  
  9.         num=num*10+(a[i]-'0');//字符串转换为数字  
  10.         i++;  
  11.     }  
  12.     printf("%d\n",num);  
  13.     char temp[5],str[5];  
  14.     while(n)  
  15.     {  
  16.         temp[j]=n%10+'0';//数字转换为字符串  
  17.         j++;  
  18.         n/=10;  
  19.     }  
  20.     temp[j]=0;  
  21.     j=j-1;  
  22.     while(j>=0)  
  23.     {  
  24.         str[x]=temp[j];//将上面的逆序转为正序  
  25.         j--;  
  26.         x++;  
  27.     }  
  28.     str[x]=0;  
  29.     printf("%s\n",str);  
  30. }  

4、求两个数组的交集

问题: 给你两个排序的数组,求两个数组的交集。
比如: A = 1 3 4 5 7, B = 2 3 5 8 9, 那么交集就是 3 5.
思路:
1. 每一次从B数组中取一值,然后在A数组里逐个比较,如果有相等的,则保存。该算法复杂度为 O(MN). M, N 分别为数组 A B 的长度。
2. 因为A B 都排过序,所以,每一次从B数组取值后,可以利用二分查找看是否在数组A里有B所对应的值,这样复杂度变成了O(N lg M)。 这里,如果N 比 M 大,可以从A中取值,然后在B中判断是否有A的值,这样,复杂度为  O(M lg N)。
3. 利用hashtable. 先把A中的值存在hashtable里,然后对于每一个B中的值,判断是否在A中存在,因为hashtable查找的平均复杂度为 O(1), 所以,整个算法复杂度为O(N), 但是,这里的空间复杂度为 O(M) 。但是,这种方法适合数组比较小的情况。因为如果A数组比较大,hashtable会出现collision的情况,这样,查找的平均复杂度就不再是 O(1)。

本文方法:
因为数组A B均排过序,所以,我们可以用两个“指针”分别指向两个数组的头部,如果其中一个比另一个小,移动小的那个数组的指针;如果相等,那么那个值是在交集里,保存该值,这时,同时移动两个数组的指针。一直这样操作下去,直到有一个指针已经超过数组范围。

  1. public LinkedList<Integer> intersection(int[] A, int[] B) {    
  2.     if (A == null || B == null || A.length == 0 || B.length == 0return null;    
  3.     LinkedList<Integer> list = new LinkedList<Integer>();    
  4.     int pointerA = 0;    
  5.     int pointerB = 0;    
  6.     while (pointerA < A.length && pointerB < B.length) {    
  7.         if (A[pointerA] < B[pointerB]) pointerA++;    
  8.         else if (A[pointerA] > B[pointerB]) pointerB++;    
  9.         else {    
  10.             list.add(A[pointerA]);    
  11.             pointerA++;    
  12.             pointerB++;    
  13.         }    
  14.     }    
  15.     return list;     
  16. }  
通过上面的算法可以得知,该算法复杂度为O(N + M).

5.0-9四则运算

  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <assert.h>  
  4. int cal(int nNum1, char op, int nNum2)  
  5. {  
  6.     if(op == '+')  
  7.     {  
  8.         return nNum1 + nNum2;  
  9.     }  
  10.     if(op == '-')  
  11.     {  
  12.         return nNum1 - nNum2;  
  13.     }  
  14.     if(op == '*')  
  15.     {  
  16.         return nNum1 * nNum2;  
  17.     }  
  18.     if(op == '/')  
  19.     {  
  20.         return nNum1 / nNum2;  
  21.     }  
  22. }  
  23.   
  24. int calculate(int len, char *expstr)  
  25. {  
  26.     assert(expstr);  
  27.     if(len < 3)  
  28.     {  
  29.         return -1;  
  30.     }  
  31.     char *p = expstr;  
  32.     int nNum1 = p[0] - '0';  
  33.     char op = p[1];  
  34.     int nNum2 = p[2] - '0';  
  35.     p += 3;  
  36.     while(*p)  
  37.     {  
  38.         if(*p=='*' || *p=='/')  
  39.         {  
  40.             nNum2 = cal(nNum2, *p, p[1]-'0');  
  41.         }  
  42.         else  
  43.         {  
  44.             nNum1 = cal(nNum1, op, nNum2);  
  45.             op = *p;  
  46.             nNum2 = p[1] - '0';  
  47.         }  
  48.         p += 2;  
  49.     }  
  50.     return cal(nNum1, op, nNum2);  
  51. }  
  52.   
  53. int main()  
  54. {  
  55.     char str[] = "8+7*2-9/3";  
  56.     scanf("%s",&str);  
  57.     int res = calculate(strlen(str), str);  
  58.     printf("result: %d\n", res);  
  59.   
  60.     return 0;  
  61. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多