第一题:通过键盘输入一串小写字母(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 = '\0';
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 = '\0'给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,让我意识到:二叉树的问题一般都可以用递归来实现算法。

 

posted on 2014-03-25 20:53  水目沾  阅读(246)  评论(0编辑  收藏  举报