2012-08-05 41 views
1

已存在標誌DEFS:容易算法使用標誌

flag1=1 
flag2=2 
flag3=4 
flag4=8 
... 
flagN=2^(N-1) 

flag=flag1+flag2+...+flagN 

如果flagI沒有設置,它的EQ 0

我有flag。哪種方法可以輕鬆檢查,例如定義了flag2

+0

這是功課? – batbrat 2012-08-05 08:45:14

+1

根據您的語言...移位操作'flagN = 1 <<(N-1)'比便宜的乘法或指數更便宜和快捷。 http://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift – klaustopher 2012-08-05 08:56:02

回答

4

回答你的問題

什麼的flag的範圍內?如果它低於2^64-1,幾乎所有方法都可以。

由於@taskinoor貼,你應該注意到:

flag1 = 000 ... ... 0001 

flag2 = 000 ... ... 0010 

flag3 = 000 ... ... 0100 

換句話說,

flag[n] = 1 << (n-1) 

所以,如果你要檢查所有位,一個for環和bitwise operation速度足以解決您的問題。像這樣(假設你能理解C/C++和標誌爲小於2^32,這可能是由持有unsigned intC/C++):

void check(unsigned int flag) 
{ 
    for (int i = 0; i < 32; ++i) 
    if ((flag & (1 << i)) != 0) 
     printf("flag%d defined!\n", i+1); 
} 

這是O(K),其k是二進制類型flag的長度。對於unsigned int,它是O(32)= O(1),幾乎在不變的時間。

如果你只是想看看有多少的標誌定義爲:

我不知道什麼是你的目的。如果你只是想算國旗多少定義,flag小於2^64,下面的方法是真棒(假設unsigned int以及):

unsigned int count_bit(unsigned int x) 
{ 
    x = (x & 0x55555555) + ((x >> 1) & 0x55555555); 
    x = (x & 0x33333333) + ((x >> 2) & 0x33333333); 
    x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F); 
    x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF); 
    x = (x & 0x0000FFFF) + ((x >> 16)& 0x0000FFFF); 
    return x; 
} 

如果調用count_bit(1234567890),它會返回12.

讓我來解釋一下這個算法。

該算法基於Divide and Conquer Algorithm。假設有一個8位整數213(11010101二進制),該算法是這樣的(每次合併兩個相鄰塊):

+-------------------------------+ 
| 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | <- x 
| 1 0 | 0 1 | 0 1 | 0 1 | <- first time merge 
| 0 0 1 1 | 0 0 1 0 | <- second time merge 
|  0 0 0 0 0 1 0 1  | <- third time (answer = 00000101 = 5) 
+-------------------------------+ 
0
Boolean isSet (flags, flagN){ 
    Return (flags & flagN) != 0; 
} 

旗作爲國旗載體,flagN旗要檢查

4

注意,在每個標誌只有一個位被設置爲1,其他都是0。

flag1 = 000 ... ... 0001 
flag2 = 000 ... ... 0010 
flag3 = 000 ... ... 0100 
// and like this 

所以,如果如果按位AND flag & flag2,那麼只有定義了flag2,結果纔會爲非零值。

r = flag & flag2; 
if r != 0 then flag2 is defined 

你可以用所有的標誌來做到這一點。

0

值得深入研究位掩碼和標誌的概念。然後你可以用你的想象力來有效地表達狀態。 (只是一個例子說明如下)

First -Define the bitmask :   0x0000001c 

什麼是,當你做的面罩上的「和」操作的二進制字符串,你會得到一個非零值?

這些是您的有效標誌值。

此位掩碼有效標誌值:0x0000001c,0x00000014,0x00000018,0x00000004,0x00000008,etc ..

因此,在應用程序中,如果你能做到以下幾點:

flagvariable |= flagvalue1 ->Enable a particular flag. 
if(flagvariable & maskvalue) :Check if a mask is enabled : 

然後不同的情況下,你需要檢查:

if(flagvariable &maskvalue ==flagvalue1) { do something} 
else 
if(flagvariable &maskvalue ==flagvalue2) {do something else}  

flagvariable &= `flagvalue1 : Clear the flag 

要更清楚地瞭解標誌和位掩碼,只需進入gdb並執行p/t並評估上述操作。