列舉及位運算

2021-10-08 07:06:12 字數 2094 閱讀 9293

目錄

1.基礎列舉演算法

2.整數列舉 

3.小數列舉

4.位運算 

5.二進位制列舉

列舉是基於已有知識來猜測答案的一種問題求解策略。列舉所有可能是問題解的答案並進行判斷。在演算法競賽中,列舉是一種基本的技巧,廣泛運用於部分分和對拍。 

**實現

int pos=-1;

for(int i=1; i<=n; i++)if(a[i]==x)

使用迴圈i= 1→n依次判斷a[i]是否等於數字x,若等於輸出即可。由於我們從1開始迴圈,找到x後使用break關閉迴圈,這樣保證我們輸出的答案即為數字x第一次出現的位置。

上面乙個例題的延伸:判斷乙個數是否為素數。我們知道,素數除了它自己和1沒有別的約數,所以列舉一下哪些是它的約數就可以

了。

bool check(int x)

&運算通常用於二進位製取位操作,例如乙個數 & 1的結果就是取二進位制的最末位。這可以用來判斷乙個整數的奇偶,二進位制的最末位為0表示該數為偶數,最末位為1表示該數為奇數。

|運算通常用於二進位制特定位上的無條件賦值,例如乙個數 | 1的結果就是把二進位制最末位強行變成1。如果需要把二進位制最末位變成0,對這個數| 1之後再減一就可以了,其實際意義就是把這個數強行變成最接近的偶數。

^運算通常用於對二進位制的特定一位進行取反操作,因為異或可以這樣定義:0和1異或0都不變,異或1則取反。^運算的逆運算是它本身,也就是說兩次異或同乙個數最後結果不變,即(a ^ b)^ b = a。

來乙個簡單的思考題 如何不借助中間變數 交換兩個數呢? 

void swap(int a, int b)

void swap(int a, int b)

~運算的定義是把記憶體中的0和1全部取反。使用~運算時要格外小心,你需要注意整數型別有沒有符號。最常見的用法是while(~scanf(「%d」,&n)){}

a << b就表示把a轉為二進位制後左移b位(在後面添b個0)。例如100的二進位制為1100100,而110010000轉成十進位制是400,那麼100 << 2 = 400。可以看出,a << b的值實際上就是a乘以2的b次方,因為在二進位制數後添乙個0就相當於該數乘以2。通常認為a << 1比a * 2更快,因為前者是更底層一些的操作。因此程式中乘以2的操作請盡量用左移一位來代替。定義一些常量可能會用到《運算。你可以方便地用1 << 16 - 1來表示65535。很多演算法和資料結構要求資料規模必須是2的冪,此時可以用《來定義max_n等常量。 

和《相似,a >> b表示二進位制右移b位(去掉末b位),相當於a除以2的b次方(取整)。我們也經常用》 1來代替整除 2,比如二分查詢、堆的插入操作等等。想辦法用》代替除法運算可以使程式效率大大提高。最大公約數的二進位制演算法用除以2操作來代替慢得出奇的求餘運算,效率可以提高60%。 

位反(~ ) > 算術 > 位左移、位右移 > 關係運算》 位與 > 位或 > 位異或 > 邏輯運算

現在教室裡有n個人,你需要選出一-些人來搬書,如何列舉所有的選法?考慮到乙個人的選和不選就是-乙個集合,因此把一乙個人在不在集合內的情況抽象為0和1,列舉數字,拆分成二進位制就可以了。但是這麼寫很繁瑣,有沒有更聰明的辦法?

int all=(1我們發現是把子集按照從大到小的順序列舉出來的。

那麼接下來我們來談談這樣列舉的正確性。首先,乙個集合它自己本身也是自己的乙個集合。我們不難發現如果兩個數a,b,a

列舉型別的位運算

stringformatflags 列舉 指定文字字串的顯示和布局資訊。此列舉有乙個屬性,允許其成員值按位組合。其中有這麼一項 nowrap 在矩形內設定格式時,禁用文字換行功能。當傳遞的是點而不是矩形時,或者指定的矩形行長為零時,已隱含此標記。當確保文字布局的時候不換行可以將stringforma...

列舉進行位運算 列舉組合z

public enum myenum 用位移運算方便的獲取多個列舉的組合變數 myenum myenum myenum.myenum1 myenum.myenum2 myenum myenum myenum.myenum3 或在組合中刪除其中一項列舉 myenum myenum.myenum1 my...

C語言 列舉與位運算

在實際問題中,有些變數的取值被限定在乙個有限的範圍內。例如,乙個星期內只有七天,一年只有十二個月,乙個班每週有六門課程等等。如果把這些量說明為整型,字元型或其它型別顯然是不妥當的。為此,c語言提供了一種稱為 列舉 的型別。在 列舉 型別的定義中列舉出所有可能的取值,被說明為該 列舉 型別的變數取值不...