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,让我意识到:二叉树的问题一般都可以用递归来实现算法。

  • 相关阅读:
    SD卡测试
    测试人员可能会遇到的问题
    HDU 1024 Max Sum Plus Plus
    HDU 1176 免费馅饼
    HDU 1257 最少拦截系统
    HDU 1087 Super Jumping! Jumping! Jumping!
    poj 1328 Radar Installation
    poj 1753 Flip Game
    HDU 1003 Max Sum
    HDU 5592 ZYB's Premutation(BestCoder Round #65 C)
  • 原文地址:https://www.cnblogs.com/zhuwbox/p/3624116.html
Copyright © 2011-2022 走看看