有疑問或錯誤盡管評論!!?
下面以C++為準。
?本文手(粘)打(貼)于各大博客之間 有問題。。。。。 我也不懂
max、min的優化
我們知道,打max、min時,要用分支(if語句)。這樣會使程序超慢。
有沒有其他方法?有的。?
當x<0時 x>>31=-1 (11111111111111111111111111111111)?
當x>=0時 x>>31=0(00000000000000000000000000000000)
所以我們可以通過作差,求出誰大誰小。
int max(int a,int b) {int m=(a-b)>>31;return a&~m|b&m; } int min(int a,int b) {int m=(a-b)>>31;return a&m|b&~m; }
以max舉例,?
當a>=b時,m=0,所以max(a,b)=a&~0|b&0=a&-1|b&0=a?
當a< b時,m=-1,所以max(a,b)=a&~-1|b&-1=a&0|b&-1=b
?
補上一個abs的優化:
int abs(int a) {int b=a>>31;return (a+b)^b; }
當a>=0時 b=0 abs(a)=a^0=a?
?
當a<0時 b=-1 abs(a)=(a-1)^-1=-a(相信大家都懂補碼的轉換方式)
?
有一點很重要的是,不要亂用!比如不能硬是將int改為long long,注意右移的位數要變!
?
手動編譯優化
格式:
#define x y
在程序中,一切出現x的地方都會變成y。?
可以省碼量,增強可讀性。
有種帶參數的,在名字(x)后打空格,里面寫參數(用逗號隔開,不用標類型)?
例如#define max(a,b) ((a)>(b)?(a):(b))
?
但是要記住它的本質,它只是單純的替換。若不加括號,也許會出現各種運算順序的錯誤。還有,不要將長的式子、函數、++或–放進去。不然會計算多遍,時間也許會炸。?
取消宏定義:
#undef x
不解釋?
還有其它的不怎么會用到,有興趣的同學可以上網搜。?
補上懶人的文件輸入輸出:
?
#define I_O(x) freopen(""#x".in","r",stdin);freopen(""#x".out","w",stdout);
?
cstring中常用的函數
這些函數應該人人都會,但還是有好多人不會。
先說一下指針與數組的關系。?
若有數組int a[N];?
則a表示a[0]的地址(&a[0])?
*a即是a[0]?
a+i=&a[i]?
*(a+i)=a[i]
memset(指針(數組名),數值(最大127,最小128,清零0),大小(sizeof ……))?
用法就是將一數組初始化。?
memcpy(指針A,指針B,大小SIZE)?
將B出復制SIZE這么多的內存到A處。
排序
sort(指針begin,指針end)?
將begin到end-1的元素以operator<進行快速排序。?
sort(begin,end,cmp)?
將begin到end-1的元素以cmp進行快速排序。?
有的孩子不知道cmp咋搞。?
比如從大到小排序
bool cmp(int a,int b) {return a>b; }
a代表前面的元素,b代表后面的元素。表示排序后的序列滿足a>b!
?
穩定性排序:?
stable_sort(begin,end);?
steble_sort(begin,end,cmp);
堆
queue里有一個,但我不愛用,因為內部一定有許多繁雜的操作,比如指針開辟一個存儲空間,會使程序變慢。?
我用algorithm里的堆。?
先注意一下比較函數int cmp(int a,int b)?
a表示后代,b表示祖先,滿足一個這樣的順序。(可以理解為大根堆)?
make_heap(begin,end)?
將begin到end-1的元素變成大根堆?
make_heap(begin,end,cmp)?
將begin到end-1的元素以cmp的順序變成大根堆?
push_heap(begin,end)?
push_heap(begin,end,cmp)?
前面begin到end-2已滿足堆的性質,將end-1的元素放進堆?
?
pop_heap(begin,end)?
pop_heap(begin,end,cmp)?
將begin的元素彈出,移至end-1處。
?