1. 程式人生 > >《程式設計珠璣》程式碼之路1:學習位操作的神器----點陣圖排序(附解決程式設計師心理問題的門路)

《程式設計珠璣》程式碼之路1:學習位操作的神器----點陣圖排序(附解決程式設計師心理問題的門路)

最近由於“閒書”讀太多,不少朋友以為我要轉當產品經理了,故想起來把最近讀的《程式設計珠璣》以及自己編寫的程式碼整理成部落格,用程式碼證明自己的清白。雖然自己比較菜不能和Google和ACM金牌大佬PK技術,作為一隻老年菜雞ACMer,經常一頓操作猛如虎,一看戰績0AC。

但相信對於剛入門的小夥伴來說,我的程式碼也許能幫上忙哈哈,同時作為一隻純種家養菜雞卻經常被各路大佬輪番吊打的我,也會結合《程式設計珠璣》提到的心理障礙簡單談一談自己的看法。

當你被誣陷要轉行的時候,跳進黃河也洗不清,但用程式碼可以。 ----- 某大廠資(meng)深(xin)演算法工程師(其實就是我)。 

好啦言歸正傳(突然一臉嚴肅的丟出問題):

給一個數字N(0 <= N <= 10000000),以及最多N個不重複數字X(1 <= X <= N),將他們排序並輸出。

要求時間複雜度O(N),Memory Limited:1MB。

這是一張圖

好啦,你都搜部落格了,說明你需要程式碼(解析在程式碼中):

#include <iostream>
#include <cstdlib>

using namespace std;

const int SIZEINT = 32;
const int MASK = 0x1f;
const int MAXINT = 10000000;
const int SHIFT = 5;

int numArray[MAXINT + 10];//要排序的數字
int sortArray[MAXINT / SIZEINT + 10];//排序後的陣列

int setBit(int array[], int num, int nSize);//設定位
int clearBit(int array[], int num, int nSize);//清空位
bool queryBit(int array[], int num, int nSize);//查詢某個數字是否存在

int bitSort(int array[], int nSize);

int main() {
	int nNum = 0;

	while (cin >> numArray[nNum]) {
		nNum++;
	}

	bitSort(numArray, nNum);
    
    //輸出
	for (int i = 0; i <= MAXINT; ++i) {
		if (queryBit(sortArray, i, nNum)) {
			cout << i << endl;
		}
	}

	system("pause");
	return 0;
}

/*
1:num >> SHIFT:選擇在陣列哪個位置存放這一位
2:(1 << (MASK & num)):MASK & num 選取後5位,2^5=32=int位數,然後把最低位移動到合適的位置
*/

int setBit(int array[], int num, int nSize){
	array[num >> SHIFT] |= (1 << (MASK & num));
	return 0;
}

int clearBit(int array[], int num, int nSize) {
	array[num >> SHIFT] &= ~(1 << (MASK & num));
	return 0;
}

bool queryBit(int array[], int num, int nSize) {
	return 1 & array[num >> SHIFT] >> (MASK & num);
}

int bitSort(int array[], int nSize) {
	
	for (int i = 0; i <= MAXINT; ++i) {
		clearBit(sortArray, i, nSize);
	}

	for (int i = 0; i < nSize; ++i) {
		setBit(sortArray, array[i], nSize);
	}
	return 0;
}

/*
1 69 3 64 1235  845214 52465 4654313 41157 4869478 5 7 52 47 7 0 10000000


*/

好啦程式碼都和關鍵解析都給了。接下來我們簡單《程式設計珠璣》中提到的一個有趣的問題:

程式設計師的主要問題與其說是技術問題,還不如說是心理問題:他不能解決問題,是因為它企圖解決錯誤的問題。問題的最終解決,是通過打破他的概念壁壘,進而去解決一個較簡單的問題而實現的。 ----- 作者原話。

作為一個長期的心理學愛好者,對作者的話深表贊同,很多大神並不是智商真的有多高,而是心態和思維上的領先,只不過很多人不願意承認而已。因為事實上,改變他們需要付出艱辛的努力。所以大家在寫程式碼的同時,一定不能忽略軟技能的培養,心理學、文學、哲學等等都是很好的提升自己的途徑。

好啦就寫到這裡啦!!