进阶之路

首页 新随笔 管理

1. 赋值运算符函数(或应说复制拷贝函数问题

class A
{
private:
	int value;
public:
	A(int n) : value(n) {}
	A(A O) { value = O.value; } // Compile Error : (const A& O)
};

因为,A a(0); A b = a; 就会使程序陷入死循环。

2. 实现 Singleton 模式 (C#)

 (博客待加设计模式总结)

3.二维数组中的查找

Sample:

二维数组:Matrix[4][4],行列都是递增。

1   2   8   9

2   4   9  12

4   7   10   13

6   8   11   15

判断 value = 7 是否在数组。

思路:从右上角开始,若大于 7 删去一列; 若小于 7 删去一行。

代码:

#include<iostream>
const int N = 4;
int data[][N] = {{1, 2, 8, 9},{ 2, 4, 9, 12},{4, 7, 10, 13}, {6, 8, 11, 15}};

bool find(int (*matrix)[N], int row, int column, int value)
{
    int r  = 0, c = column - 1;
    while(r < row && c >= 0)
    {
        if(matrix[r][c] == value) return true;
        if(matrix[r][c] > value) --c;
        else ++r;
    }
    return false;
}

int main()
{
    std::cout << find(data, 4, 4, 10) << std::endl;
    return 0;
}
View Code

4.替换空格  时间:O(n) 空间:O(1)

 Sample:

输入:  S:"We are happy."

输出:S:"We%20are%20happy."

 1 #include<stdio.h>
 2 #include<string.h>
 3 const int N = 18;
 4 /* length  is the full capacity of the string, max number of elements is length-1*/
 5 void ReplaceBank(char s[], int length){
 6     if(s == NULL && length <= 0) return; // program robustness 
 7     int nowLength = -1, numberOfBlank = 0;
 8     while(s[++nowLength] != '\0'){
 9         if(s[nowLength] == ' ') ++numberOfBlank;
10     }
11     int newLength = nowLength + numberOfBlank * 2;  // newLength is the number of elements 
12     if(newLength >= length) return;
13     
14     int idOfNow = nowLength, idOfNew = newLength; // both point to '/0' 
15     while(idOfNow >= 0){      /* key program */
16         if(s[idOfNow] == ' ') {
17             strncpy(s+idOfNew-2, "%20", 3);
18             idOfNew -= 3;
19             --idOfNow; 
20         }else
21             s[idOfNew--] = s[idOfNow--];
22     }
23 }
24 
25 int main(){
26     char s[N] = "We are happy.";
27     puts(s);
28     ReplaceBank(s,N);
29     puts(s);
30     return 0;
31 }
Code

 5.从尾到头打印链表

 1. 询问是否可以改变链表结构,若可以,则空间O(1);否则,

 2. 使用栈,或者递归。

  a. 使用栈:

 1 #include <iostream>
 2 #include <string>
 3 #include <stack>
 4 
 5 struct LinkNode{
 6     char e;
 7     LinkNode *next;
 8 };
 9 
10 void print(LinkNode *Head)
11 {
12     std::stack<char> st;
13     while(Head != NULL)
14     {
15         st.push(Head->e);
16         Head = Head->next;
17     }
18     while(!st.empty())
19     {
20         printf("%c ", st.top());
21         st.pop();
22     }
23     printf("\n");
24 }
25 
26 LinkNode* init(const std::string &s)
27 {
28     size_t i = 0;
29     LinkNode *head, *p;
30     p = head = NULL;
31     while(i < s.length())
32     {
33         LinkNode *p2 = new LinkNode;
34         p2->e = s[i++]; p2->next = NULL;
35         if(head == NULL)
36             head = p = p2;
37         else
38         {
39             p->next = p2;
40             p = p->next;
41         }
42     }
43     return head;
44 }
45 void release(LinkNode *Head){
46     if(Head == NULL) return;
47     release(Head->next);
48     delete[] Head;
49     Head = NULL;
50 }
51 int main()
52 {
53     const std::string s = "ABCDEFG";
54     LinkNode *Head = init(s);
55     print(Head);
56     release(Head);
57     return 0;
58 }
Code

  b. 使用递归:

void RecursivePrint(LinkNode *Head)
{
    if(Head == NULL) return;
    RecursivePrint(Head->next);
    printf("%c ", Head->e);
}

 6. 重建二叉树

  a. 前序 && 中序  

 1 #include <cstdio>
 2 #include <queue>
 3 struct BTNode{
 4     int value;
 5     BTNode *pLeft;
 6     BTNode *pRight;
 7     BTNode(int x) : value(x), pLeft(NULL), pRight(NULL) {}
 8 };
 9 
10 BTNode* constructCore(int *startPreOrder, int *endPreOrder, int *startInOrder, int *endInOrder)
11 {
12     int rootValue = startPreOrder[0];
13     BTNode *root = new BTNode(rootValue);
14     int *rootInOrder = startInOrder;
15     while(*rootInOrder != rootValue && rootInOrder <= endInOrder) ++rootInOrder;
16     if(*rootInOrder != rootValue) { printf("Invalid Input!"); return NULL; }
17 
18     int leftLength = rootInOrder - startInOrder;
19     if(leftLength > 0)
20     {
21         root->pLeft = constructCore(startPreOrder + 1, startPreOrder + leftLength,
22             startInOrder, startInOrder + leftLength - 1);
23     }
24     if(rootInOrder != endInOrder)
25     {
26         root->pRight = constructCore(startPreOrder + leftLength + 1, endPreOrder,
27             rootInOrder + 1, endInOrder);
28     }
29     return root;
30 }
31 
32 BTNode* construct(int *preOrder, int *inOrder, int length)
33 {
34     if(preOrder == NULL || inOrder == NULL || length <= 0) 
35         return NULL;
36     return constructCore(preOrder, preOrder + length - 1, inOrder, inOrder + length -1);
37 }
38 void print(BTNode *root)
39 {
40     if(root == NULL) return;
41 
42     std::queue<BTNode*> qu;
43     qu.push(root);
44     while(!qu.empty())
45     {
46         BTNode *p = qu.front();
47         qu.pop();
48         if(p->pLeft) qu.push(p->pLeft);
49         if(p->pRight) qu.push(p->pRight);
50         printf("%d ", p->value);
51     }
52 }
53 void release(BTNode *root)
54 {
55     if(root == NULL) return;
56     release(root->pLeft);
57     release(root->pRight);
58     delete[] root;
59     root = NULL;
60 }
61 
62 int main()
63 {
64     int preOrder[] = {1, 2, 4, 7, 3, 5, 6, 8};
65     int inOrder[] = {4, 7, 2, 1, 5, 3, 8, 6};
66     BTNode *root = construct(preOrder, inOrder, 8);
67     print(root);
68     release(root);
69     return 0;
70 }
Code

    二叉树的各种遍历:

  1 #include <cstdio>
  2 #include <queue>
  3 #include <stack>
  4 struct BTNode{
  5     int value;
  6     BTNode *pLeft;
  7     BTNode *pRight;
  8     BTNode(int x) : value(x), pLeft(NULL), pRight(NULL) {}
  9 };
 10 
 11 BTNode* constructCore(int *startPreOrder, int *endPreOrder, int *startInOrder, int *endInOrder)
 12 {
 13     int rootValue = startPreOrder[0];
 14     BTNode *root = new BTNode(rootValue);
 15     int *rootInOrder = startInOrder;
 16     while(*rootInOrder != rootValue && rootInOrder <= endInOrder) ++rootInOrder;
 17     if(*rootInOrder != rootValue) { printf("Invalid Input!\n"); return NULL; }
 18 
 19     int leftLength = rootInOrder - startInOrder;
 20     if(leftLength > 0)
 21     {
 22         root->pLeft = constructCore(startPreOrder + 1, startPreOrder + leftLength,
 23             startInOrder, startInOrder + leftLength - 1);
 24     }
 25     if(rootInOrder != endInOrder)
 26     {
 27         root->pRight = constructCore(startPreOrder + leftLength + 1, endPreOrder,
 28             rootInOrder + 1, endInOrder);
 29     }
 30     return root;
 31 }
 32 
 33 BTNode* construct(int *preOrder, int *inOrder, int length)
 34 {
 35     if(preOrder == NULL || inOrder == NULL || length <= 0) 
 36         return NULL;
 37     return constructCore(preOrder, preOrder + length - 1, inOrder, inOrder + length -1);
 38 }
 39 void levelOrderPrint(BTNode *root) 
 40 {
 41     if(root == NULL) return;
 42     printf("BFS:");
 43     std::queue<BTNode*> qu;
 44     qu.push(root);
 45     while(!qu.empty())
 46     {
 47         BTNode *p = qu.front();
 48         qu.pop();
 49         if(p->pLeft) qu.push(p->pLeft);
 50         if(p->pRight) qu.push(p->pRight);
 51         printf("%-3d ", p->value);
 52     }
 53     printf("\n");
 54 }
 55 void preORderPrint2(BTNode *root) // preORder
 56 {
 57     if(root == NULL) return;
 58     printf("DLR: ");
 59     std::stack<BTNode*> st;
 60     st.push(root);
 61     while(!st.empty())
 62     {
 63         BTNode *p = st.top();
 64         st.pop();
 65         if(p->pRight) st.push(p->pRight);
 66         if(p->pLeft) st.push(p->pLeft);
 67         printf("%-3d ", p->value);
 68     }
 69     printf("\n");
 70 }
 71 void inOrderPrint3(BTNode *root) // inOrder
 72 {
 73     if(root == NULL) return;
 74     printf("LDR: ");
 75     std::stack<BTNode*> st;
 76     st.push(root);
 77     BTNode *p = root;
 78     while(p->pLeft) 
 79     {
 80         st.push(p->pLeft);
 81         p = p->pLeft;
 82     }
 83     while(!st.empty())
 84     {
 85         p = st.top();
 86         st.pop();
 87         if(p->pRight) 
 88         {
 89             BTNode *q = p->pRight;
 90             st.push(q);
 91             while(q->pLeft) { st.push(q->pLeft); q = q->pLeft; }
 92         }
 93         printf("%-3d ", p->value);
 94     }
 95     printf("\n");
 96 }
 97 void postOrderPrint4(BTNode *root) // postOrder
 98 {
 99     if(root == NULL) return;
100     printf("LRD: ");
101     std::stack<BTNode*>st;
102     st.push(root);
103     BTNode *p = root;
104     while(p->pLeft || p->pRight)
105     {
106         while(p->pLeft) { st.push(p->pLeft); p = p->pLeft; }
107         if(p->pRight) { st.push(p->pRight); p = p->pRight; }
108     }
109     //bool tag = true;
110     while(!st.empty())
111     {
112         BTNode *q = st.top();
113         st.pop();
114         if(!st.empty())
115         {
116             p = st.top();
117             if(p->pRight && p->pRight != q) 
118             { 
119                 st.push(p->pRight); p = p->pRight; 
120                 while(p->pLeft || p->pRight)
121                 {
122                     while(p->pLeft) { st.push(p->pLeft); p = p->pLeft; }
123                     if(p->pRight) { st.push(p->pRight); p = p->pRight; }
124                 }
125             }
126         }
127         printf("%-3d ", q->value);
128     }
129     printf("\n");
130 }
131 void DFSPrint(BTNode *root,const int nVertex)
132 {
133     if(root == NULL) return;
134     printf("DFS: ");
135     bool *visit = new bool[nVertex];
136     memset(visit, false, nVertex);
137     std::stack<BTNode*> st;
138     st.push(root);
139     visit[root->value] = true;
140     while(!st.empty())
141     {
142         BTNode *p = st.top();
143         st.pop();
144         if(p->pRight && !visit[p->pRight->value]) { st.push(p->pRight); visit[p->pRight->value] = true; }
145         if(p->pLeft && !visit[p->pLeft->value]) { st.push(p->pLeft); visit[p->pLeft->value];}
146         printf("%-3d ", p->value);
147     }
148     printf("\n");
149 }
150 void release(BTNode *root)
151 {
152     if(root == NULL) return;
153     release(root->pLeft);
154     release(root->pRight);
155     delete[] root;
156     root = NULL;
157 }
158 
159 int main()
160 {
161     int preOrder[] = {1, 2, 4, 8, 9, 5, 10, 11, 3, 6, 12, 13, 7, 14, 15};
162     int inOrder[] = {8, 4, 9, 2, 10, 5, 10, 1, 12, 6, 13, 3, 14, 7, 15};
163     BTNode *root = construct(preOrder, inOrder, 15);
164     levelOrderPrint(root);
165     preORderPrint2(root);
166     inOrderPrint3(root);
167     postOrderPrint4(root);
168     DFSPrint(root, 15+1);
169     release(root);
170     return 0;
171 }
Code

 7.用两个栈实现队列

 1 #include <cstdio>
 2 #include <stack>
 3 #include <exception>
 4 template<typename T> class CQueue
 5 {
 6 public:
 7     void appendTail(T x);
 8     T deleteHead();
 9 private:
10     std::stack<T> st1;
11     std::stack<T> st2;
12 };
13 template<typename T>void CQueue<T>::appendTail(T x)
14 {
15     st1.push(x);
16 }
17 template<typename T>T CQueue<T>::deleteHead()
18 {
19     if(st2.empty())
20     {
21         if(st1.empty()) throw new std::exception("queue is empty!");
22         while(!st1.empty())
23         {
24             st2.push(st1.top());
25             st1.pop();
26         }
27     }
28     T v = st2.top();
29     st2.pop();
30     return v;
31 }
32 
33 int main()
34 {
35     printf("Test int:\n");
36     CQueue<int> qu;
37     qu.appendTail(10);
38     qu.appendTail(2);
39     printf("%d\n",qu.deleteHead());
40     printf("%d\n",qu.deleteHead());
41 
42     printf("Test char*:\n");
43     CQueue<char*> qu2;
44     qu2.appendTail("Hello");
45     qu2.appendTail("World!");
46     printf("%s\n",qu2.deleteHead());
47     printf("%s\n",qu2.deleteHead());
48     //printf("%s\n",qu2.deleteHead());
49     return 0;
50 }
Code

 8.旋转数组的最小数字

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int MinInorder(int *numbers, int low, int high)
 5 {
 6     int minNum = numbers[low];
 7     while(++low <= high)
 8     {
 9         if(numbers[low] < minNum) 
10             minNum = numbers[low];
11     }
12     return minNum;
13 }
14 
15 int Min(int *numbers, int length)
16 {
17     if(numbers == NULL || length <= 0) throw new exception("Invalid parameters!");
18     int low = 0, high = length - 1;
19     int mid = low;   // note
20     while(numbers[low] >= numbers[high]) // note >= 
21     {
22         if(high - low == 1)
23         {
24             mid = high;
25             break;
26         }
27         mid = (low + high) >> 1;
28         if(numbers[mid] == numbers[low] && numbers[mid] == numbers[high]) return MinInorder(numbers, low, high);
29         else if(numbers[mid] >= numbers[low]) low = mid;
30         else if(numbers[mid] <= numbers[high]) high = mid;
31     }
32     return numbers[mid];
33 }
34 
35 int main()
36 {
37     int test1[] = {4, 5, 1, 2, 3};
38     cout << "Test1: " << Min(test1, sizeof(test1)/4) << endl;
39 
40     int test2[] = {1, 1, 1, 0, 1};
41     cout << "Test2: " << Min(test2, sizeof(test2)/4) << endl;
42 
43     return 0;
44 }
Code

9.斐波那契数列第 n 项

  a. 动态规划(从低到高保存结果)

int Fibonacci1(unsigned long long N)
{
	long long fibN;
	long long a[] = {0, 1};
	if(N < 2) return a[N];
	while(N >= 2)
	{
		fibN = (a[0] + a[1]) % M;
		a[0] = a[1];
		a[1] = fibN;
		--N;
	}
	return (int)fibN;
}

 b1.矩阵二分乘(递归)

const int M = 1e+9 +7 ; 
struct Matrix{
	long long e[2][2];
};
Matrix Mat;

Matrix multiplyMatrix(Matrix &A, Matrix &B)
{
	Matrix C;
	for(int i = 0; i < 2; ++i){
		for(int j = 0; j < 2; ++j){
			C.e[i][j] = ((A.e[i][0] * B.e[0][j]) % M + (A.e[i][1] * B.e[1][j]) % M) % M;
		}
	}
	return C;
}
Matrix getMatrix(long long n)
{
	if(n == 1) return Mat;
	Matrix tem = getMatrix(n>>1);
	tem = multiplyMatrix(tem,tem);
	if((n & 0x1) == 0) return tem;
	else 
		return multiplyMatrix(Mat,tem);
}

int Fibonacci2(long long N)
{
	if(N == 0) return 0;
	if(N == 1) return 1;
	Mat.e[0][0] = 1; Mat.e[0][1] = 1;
	Mat.e[1][0] = 1; Mat.e[1][1] = 0;
	Matrix result = getMatrix(N-1);
	return (int)result.e[0][0];
}

b2.  矩阵二分乘(非递归)

const int M = 1000000007; 
struct Matrix{
	long long e[2][2];
};
Matrix Mat;

Matrix multiplyMatrix(Matrix &A, Matrix &B)
{
	Matrix C;
	for(int i = 0; i < 2; ++i){
		for(int j = 0; j < 2; ++j){
			C.e[i][j] = ((A.e[i][0] * B.e[0][j]) % M + (A.e[i][1] * B.e[1][j]) % M) % M;
		}
	}
	return C;
}
Matrix getMatrix(Matrix base, long long N)
{
	Matrix T;                   // set one unit matrix
	T.e[0][0] = T.e[1][1] = 1;
	T.e[0][1] = T.e[1][0] = 0;
	while(N - 1 != 0)
	{
		if(N & 0x1) T = multiplyMatrix(T, base);
		base = multiplyMatrix(base, base);
		N >>= 1;
	}
	return multiplyMatrix(T, base);
}

int Fibonacci2(long long N)
{
	if(N == 0) return 0;
	if(N == 1) return 1;
	Mat.e[0][0] = 1; Mat.e[0][1] = 1;
	Mat.e[1][0] = 1; Mat.e[1][1] = 0;
	Matrix result = getMatrix(Mat, N-1);
	return (int)result.e[0][0];
}

 两种方法效率的比较:

 1 #include <iostream>
 2 #include <ctime>
 3 using namespace std;
 4 const int M = 1000000007; 
 5 struct Matrix{
 6     long long e[2][2];
 7 };
 8 Matrix Mat;
 9 
10 Matrix multiplyMatrix(Matrix &A, Matrix &B)
11 {
12     Matrix C;
13     for(int i = 0; i < 2; ++i){
14         for(int j = 0; j < 2; ++j){
15             C.e[i][j] = ((A.e[i][0] * B.e[0][j]) % M + (A.e[i][1] * B.e[1][j]) % M) % M;
16         }
17     }
18     return C;
19 }
20 Matrix getMatrix(Matrix base, long long N)
21 {
22     Matrix T;                   // set one unit matrix
23     T.e[0][0] = T.e[1][1] = 1;
24     T.e[0][1] = T.e[1][0] = 0;
25     while(N - 1 != 0)
26     {
27         if(N & 0x1) T = multiplyMatrix(T, base);
28         base = multiplyMatrix(base, base);
29         N >>= 1;
30     }
31     return multiplyMatrix(T, base);
32 }
33 
34 int Fibonacci2(long long N)
35 {
36     if(N == 0) return 0;
37     if(N == 1) return 1;
38     Mat.e[0][0] = 1; Mat.e[0][1] = 1;
39     Mat.e[1][0] = 1; Mat.e[1][1] = 0;
40     Matrix result = getMatrix(Mat, N-1);
41     return (int)result.e[0][0];
42 }
43 
44 int Fibonacci1(long long N)
45 {
46     long long fibN;
47     long long a[] = {0, 1};
48     if(N < 2) return (int)a[N];
49     while(N >= 2)
50     {
51         fibN = (a[0] + a[1]) % M;
52         a[0] = a[1];
53         a[1] = fibN;
54         --N;
55     }
56     return (int)fibN;
57 }
58 
59 int main()
60 {
61     unsigned long long N;
62     while(cin >> N)
63     {
64         /* method 1: DP  */
65         clock_t start = clock();
66         int fibN = Fibonacci1(N);
67         clock_t end = clock();
68         cout << "method1:" << fibN << " time: " << end-start << "ms" << endl;
69         /* method 2   */
70         start = clock();
71         fibN = Fibonacci2(N);
72         end = clock();
73         cout << "method2:" << fibN << " time: " << end-start << "ms" << endl;
74     }
75     return 0;
76 }
Code

10.一个整数的二进制表示中 1 的个数。(包含正负数)

   需要注意的是:—1 >> (任意位)  == —1; 负数 >> +∞ == —1。 ((—1)10 == (0xffffffff)16  )

  a. 利用辅助变量,每次判断 n 的一位。

 1 int numberOf1(int n)
 2 {
 3     int count = 0;
 4     int flag = 1;
 5     while(flag)
 6     {
 7         if(n & flag) count ++;
 8         flag <<= 1;
 9     }
10     return count;
11 }
Code

 b. 利用 n 的性质。

 1 #include <iostream>
 2 int numberOf1(int n){
 3     int count = 0;
 4     while(n){
 5         count ++;
 6         n &= (n-1);
 7     }
 8     return count;
 9 }
10 int main(){
11     int N;
12     while(std::cin >> N){
13         std::cout << "has 1: " << numberOf1(N) << std::endl;
14     }
15     return 0;
16 }
Code

 

 

posted on 2014-04-15 22:03  进阶之路  阅读(472)  评论(0编辑  收藏  举报