zoukankan      html  css  js  c++  java
  • 面试试题

    第一题:通过键盘输入一串小写字母(a~z)组成的字符串。请编写一个字符串压缩程序,将字符串中连续出席的重复字母进行压缩,并输出压缩后的字符串。

      压缩规则:
        1、仅压缩连续重复出现的字符。比如字符串"abcbc"由于无连续重复字符,压缩后的字符串还是"abcbc"。
        2、压缩字段的格式为"字符重复的次数+字符"。例如:字符串"xxxyyyyyyz"压缩后就成为"3x6yz"。

      下面是我写的代码:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 void stringZip(const char *pInputStr,long linputLen,char *pOutputStr)
     6 {
     7     char ccount = '0';
     8     int  i        = 0;
     9     const char *pPoint1 = pInputStr;
    10     const char *pPoint2 = pInputStr;
    11     
    12     //判断指针是否为空
    13     if(pInputStr == NULL)
    14     {
    15         pOutputStr = NULL;
    16         return ;
    17     }
    18     for(i=0;i < linputLen;)
    19     {
    20         ccount = '0';
    21         while((*pPoint1)==(*pPoint2))
    22         {
    23             i++;        //控制循环
    24             ccount  ++;
    25             pPoint2 ++;
    26         }    
    27         //跳出循环赛说明两个指针所指的字符开始不相等
    28         if(ccount > '1')    *pOutputStr++ = ccount;    
    29         *pOutputStr++      = *pPoint1;            
    30         pPoint1 = pPoint2;
    31     }
    32     *pOutputStr = '';
    33 }
    34 
    35 int main()
    36 {
    37     char *pOutputStr =  (char *)malloc(sizeof(char)*20); 
    38     char *pInputStr = "Hello,world!";
    39     stringZip(pInputStr,strlen(pInputStr),pOutputStr);
    40     cout << "Output:" << pOutputStr << endl;
    41     return 0;
    42 }

      好久没写代码了,这次写代码犯了几个错误:

        1.sizeof和strlen计算字符串大小出来的结果是不一样的。

        2.非C语言风格的字符串用cout打印出来会乱码。

        3.居然这样p = ''给p所指向的内容赋值。

    第二题:已知memcpy的函数为: void* memcpy(void *dest , const void* src , size_t count)其中dest是目的指针,src是源指针。不调用c++/c的memcpy库函数,请编写memcpy。

      下面是参考代码:

     1 void* memcpy_(void *dest , const void* src , size_t count)
     2 {
     3     //安全检查
     4     assert(dest != NULL && src != NULL);
     5     unsigned char *pdest      = (unsigned char *)dest;      
     6         const unsigned char *psrc = (const unsigned char *)src;
     7 
     8     assert(!(psrc <= pdest && pdest < psrc+count));      
     9         assert(!(pdest<= psrc  && psrc  < pdest+count));
    10     while(count--)
    11     {
    12         *pdest = *psrc;
    13         pdest++;
    14         psrc ++;
    15     }
    16     return dest;
    17 }
    18 
    19 int main()
    20 {
    21     char *pOutputStr =  (char *)malloc(sizeof(char)*20); 
    22     char dest[] = "abcdefgh";
    23     char *src  = "123456";
    24     memcpy_(dest,src,2);
    25     cout << "Output:" << dest << endl;
    26     return 0;
    27 }

      这题我做的不对,没做防止内存重复的检查,其次又遇到了几个问题:

        1.char *str = "Hello,world!";是个字符串常量,不能对其赋值。

        2.不能对void * 指针进行算术操作,会报unknow size的错

    第三题:已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={5,15,35,25},完成计算后A={10,20,30}。

       我的代码如下(只有函数):

     1 struct node    
     2 {    
     3     int elem;    
     4     node* next;    
     5 };
     6 //LA,LB是集合,不存在重复元素
     7 void difference(node** LA , node* LB)
     8 {
     9     //安全检查
    10     node *lpB = LB,*lpA1 = *LA,*lpA2 = *LA;
    11     assert((LB != NULL)&&(* LA) != NULL);
    12     //如果是用一般的方法,复杂度是O(m*n)
    13     while(lpA2 != NULL)
    14     {
    15         lpB = LB;
    16         while(lpB != NULL)
    17         {
    18             if(lpA2 == (*LA))    //如果是首节点
    19             {
    20                 if(lpB->elem == lpA2->elem)
    21                 {
    22                     *LA = (*LA)->next;    //将首节点指向下一个
    23                     free(lpA2);            //释放被删除的节点
    24                     lpA1 = lpA2 = *LA;  //重新指向
    25                 }
    26                 else
    27                 {
    28                     lpA2 = lpA1->next; 
    29                 }
    30             }
    31             else
    32             {
    33                 if(lpB->elem == lpA2->elem)
    34                 {
    35                     lpA1 = lpA2->next;
    36                     free(lpA2);
    37                     lpA2 = lpA1->next;    
    38                 }
    39                 {
    40                     lpA1 = lpA2;
    41                     lpA2 = lpA2->next;
    42                 }
    43             }
    44         }
    45     }
    46 }

     第四题:把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。

    10

    /

    6 14

    / /

    4 8 12 16 转换成双向链表 4=6=8=10=12=14=16。 首先我们定义的二元查找树节点的数据结构如下:

    struct BSTreeNode {

      int m_nValue; // value of node

      BSTreeNode *m_pLeft; // left child of node

      BSTreeNode *m_pRight; // right child of node

    };

    代码如下如下,参考:http://blog.csdn.net/v_JULY_v/article/details/6126406

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 struct BSTreeNode    //二元查找树的节点
     6 {
     7     int m_nValue;
     8     BSTreeNode *m_pLeft;
     9     BSTreeNode *m_pRight;
    10 };
    11 typedef BSTreeNode DoubleList;
    12 DoubleList *pHead   = NULL;
    13 DoubleList *pIndex  = NULL;
    14 //创建二元查找树
    15 void addBSTreeNode(BSTreeNode *&pCurrent,int value)
    16 {
    17     if(NULL == pCurrent)    //如果是空的话就创建节点
    18     {
    19         BSTreeNode *pBSTree = new BSTreeNode();
    20         pBSTree->m_pLeft  = NULL;
    21         pBSTree->m_pRight = NULL;
    22         pBSTree->m_nValue = value;
    23         pCurrent = pBSTree;
    24     }
    25     else
    26     {
    27         if(pCurrent->m_nValue > value)
    28         {
    29             addBSTreeNode(pCurrent->m_pLeft,value);
    30         }
    31         else if(pCurrent->m_nValue < value)
    32         {
    33             addBSTreeNode(pCurrent->m_pRight,value);
    34         }
    35         else
    36         {
    37             cout << "重复插入";
    38         }
    39     }
    40 
    41 }
    42 
    43 //遍历二元查找树 中序
    44 void inorderBSTree(BSTreeNode *pCurrent)
    45 {
    46     if(NULL == pCurrent)
    47     {
    48         return ;
    49     }
    50     else
    51     {
    52         inorderBSTree(pCurrent->m_pLeft);
    53         {
    54             if(NULL == pHead)
    55             {
    56                 pHead = pCurrent;    //首节点
    57                 pIndex= pCurrent;
    58             }
    59             else
    60             {
    61                 pIndex->m_pRight = pCurrent;
    62                 pCurrent->m_pLeft= pIndex;
    63                 pIndex             = pCurrent;
    64             }
    65         }
    66         inorderBSTree(pCurrent->m_pRight);
    67     }
    68 }
    69 
    70 int main()
    71 {
    72     BSTreeNode * pRoot = NULL;
    73         addBSTreeNode(pRoot, 10);
    74         addBSTreeNode(pRoot, 4);
    75         addBSTreeNode(pRoot, 6);
    76         addBSTreeNode(pRoot, 8);
    77         addBSTreeNode(pRoot, 12);
    78         addBSTreeNode(pRoot, 14);
    79         addBSTreeNode(pRoot, 15);
    80         addBSTreeNode(pRoot, 16);
    81     inorderBSTree(pRoot);
    82     return 0;
    83 }

    第五题: 判断整数序列是不是二元查找树的后序遍历结果
    题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。
    如果是返回true,否则返回false。
    例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果:
          8
         /
        6  10
       /   /
      5  7 9 11
    因此返回true。
    如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 bool checkIsOrNotAfterOrderBSTree(int *pc,int len)
     6 {
     7     bool left = true, right = true;
     8     int i = 0,j = 0,root = pc[len-1];    //根肯定是最后一位
     9     if(pc == NULL || len <= 0 )
    10     {
    11         return false;
    12     }
    13     //找到根的左节点的结束位置
    14     for(i = 0; i < len - 1; ++i)  //注意这里的,len一定要减一,否则会与自身比较,陷入死循环
    15     {
    16         if(pc[i] > root)
    17             break;
    18     }
    19     //剩下的都是右节点了,判断右节点是否都大于根节点
    20     for(j = i; j < len - 1; ++j)
    21     {
    22         if(pc[j] < root)
    23         {
    24             return false;
    25         }
    26     }
    27     if(i > 0)
    28         left = checkIsOrNotAfterOrderBSTree(pc,i);
    29     if(len - i > 1)
    30         right=  checkIsOrNotAfterOrderBSTree(&pc[i],len - i - 1);    //减1是为了减掉根
    31     return (left&&right);
    32 }
    33 int main()
    34 {
    35     int squene[] = {5,4,6,9,11,10,8};
    36     if(checkIsOrNotAfterOrderBSTree(squene,7))
    37         cout << "Yes" << endl;
    38     else
    39         cout << "No" << endl;
    40     return 0;
    41 }

      这题是我参考http://blog.csdn.net/v_JULY_v/article/details/6126406,让我意识到:二叉树的问题一般都可以用递归来实现算法。

  • 相关阅读:
    KMP算法
    数据库建立索引为什么会加快查询速度
    腾讯2014实习生4月20日笔试题(分析与解答)
    智能指针auto_ptr & shared_ptr
    用C++实现一个不能被继承的类
    2014金山笔试_编写一个数组类 MyVector
    TCP分组交换详解
    子网掩码的计算
    服务器端 安装svn
    yii2之ActiveForm表单使用
  • 原文地址:https://www.cnblogs.com/zhuwbox/p/3624116.html
Copyright © 2011-2022 走看看