代码改变世界

某公司的几道面试题

2011-07-13 09:14  menggucaoyuan  阅读(678)  评论(8编辑  收藏

    在sz的tx面试时,有以下几道好题,面试时没有思路,面试人给提示下,觉得算法很好。不敢独享,特列出。朋友中又觉得我把题列出来是不妥当行为的,请及时告知,我会马上删除。

 题1:找出集合{A, B, C, ..., Z}的所有子集。
分析:如果集合为{A,B,C},则所有的子集如下:
     A  B  C
     0  0  0   值为0 代表空集
     0  0  1   值为1 代表{C}
     0  1  0   值为2 代表{B}
     0  1  1   值为3 代表{B,C}
     1  0  0   值为4 代表{A} 
     1  0  1   值为5 代表{A,C}
     1  1  0   值为6 代表{A,B}
     1  1  1   值为7 代表{A,B,C}
     能看出点什么规律吧?集合的总数为2 ^ 3 = 8个,子集取其值为1对应的字母的集合。
代码:
     void GetAllSubsets(void)
     {
         char cSet[] = {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z};
         int  nSize  = sizeof(cSet) / sizeof(cSet[0]);
         int nStart = 0;
         int nEnd   = pow(2, nSize);
         int nGuard = nStart;
         int nIdxI  = 0;
         while (nGuard < nEnd)
         {
             nStart = nGuard;
             nIdxI  = 0;
             while (nIdxI < nSize)
             {
                 if ((nGuard >> 1) & 0x0)
                 {
                     printf("%c", cSet[nIdxI]);
                 }//if
                 nIdxI++;
             }// nIdxI, while
             printf("\n");
             nGuard = nStart++;
         }//nGuard, while
     }

题2:有一个无序的整数集合,找出符合下列条件的所有整数:
     1、整数值为x,则整数前面的所有数都小于x;
     2、整数值为x,则整数后面的所有数都大于x;
要求算法时间复杂度为O(n)。
分析:整数x把集合分成了前后两个子集合,如果前面集合中最大的数值为max,后面集合最小值为min,则上面的这个条件可以转化为下面这个条件:
      max < x && x < min
代码:
     void GetStableElem(void)
     {
         int nSet[8] = {2, 1, 3, 7, 5, 6, 10, 13};
         int nA[8];
         int nB[8];
         memset(nA, 2, 8);
         memset(nB, 13, 8);
        
         int nIdxI = 0;
         int nMin  = nSet[0];
         for (nIdxI = 1; nIdxI < 8; nIdxI++)
         {
             nA[nIdxI] = nMin;
             if (nSet[nIdxI] < nMin)
             {
                 nMin = nSet[nIdxI];
             }//if
         }// nIdxI, for

         int nMax = nSet[7];
         for (nIdxI = 6; -1 < nIdxI; nIdxI--)
         {
             nB[nIdxI] = nMax;
             if (nMax < nSet[nIdxI])
             {
                 nMax = nSet[nIdxI];
             }//if
         }//nIdxI, for

         int nStableElem[8] = {0};
         int nIdxJ = 0;
         for (nIdxI = 0; nIdxI < 8; nIdxI++)
         {
             if (nA[nIdxI] < nSet[nIdxI] && nSet[nIdxI] < nB[nIdxI])
             {
                 nStableElem[nIdxJ++] = nIdxI;
             }//if
         }//nIdxI, for
     }

题3:有整数集合A和集合B,二者都是升序排列,请判断B是否是A的子集。要求算法时间复杂度为O(n)。
分析:这道题类似于进行多项式加法运算时,对逐个元素的次数进行比较。
代码:
    int nA[5] = {0, 1, 6, 8, 7};
    int nB[2] = {1, 6};  
    bool CheckSubSet(int* nSet, int nSetSize, int* nSubSet, int nSSSize)
    {
        if (NULL == nSet || NULL == nSubSet || nSetSize <= 0 || nSSSize <= 0)
        {
            return false;
        }//if       

        if (nSet[nSetSize - 1] <= nSubSet[0] || nSubSet[nSSSize - 1] <= nSet[0])
        {
            return false;
        }//if

        int nIdxI = 0;
        int nIdxJ = 0;
        while (nIdxI < nSize && nIdxJ < nSSSize)
        {
            if (nSet[nIdxI] == nSubSet[nIdxJ])
            {
                nIdxI++;
                nIdxJ++;
            }
            else if(nSubSet[nIdxJ] < nSet[nIdxI])
            {
                nIdxI++;
            }
            else
            {
                return false;
            }
        }//nIdxI, nIdxJ, while

        if (nIdxI <= nSize && nIdxJ == nSSSize)
        {
            return true;
        }//nIdxI, nIdxJ, if

        return false;
    }

题4:有如下代码:
     int a = 123;
     printf("%s", a);
     运算结果是?
分析:当时没做出来,后来用VC2008编译后,程序运行时直接崩溃。请高人给分析下。

题5:一个C程序运行中,如果用malloc申请空间不释放,后果是?

分析:也请各位给分析下。