簡體   English   中英

用二進制表示的數字的偶數和奇數位置1的個數是多少?

[英]What is the number of 1's at even and odd places of a number in binary representation?

無論是按位還是64位范圍內的整數的任何函數,它們是實現它的更快方法。我已經實現了。

/* 
Find F(i)=abs(a(i)-b(i))
a(i)=number of 1's in even position 
b(i)=number of 1's in odd position 
for an integer i, where i fits in 64-bit
*/
//function calculate the above equation
//returns the answer
long long int F(long long int k)
{
    //size of array is taken for 64-bit number
    int a[64]={0},i,a,b;
    long long int m;
    m=k;
    //convert long long int into binary 
    for(i=63;i>-1;i--)
    {
        if(m==1||m==0)
        {
            a[i]=m;
            break;       //exit the for loop
        }
        a[i]=m%2;        //storing bit by bit
        m/=2;           
    }
    // initialized with a value of zero
    a=0;
    b=0;
    //find first bit having 1
    int f;
    for(i=0;i<64;i++)
    {
        if(a[i]==1)
        {
            f=i;
            break;
        }
    }
    //calculating the number of 1's in even and odd positions
    for(i=f;i<64;i++)
    {
        if(a[i]==1)
        {
            if((63-f)%2==0)
            {
                a++;          //1's in even positions
            }
            else
            {
                b++;          //1's in odd positions
            }
        }
    }

    //return the answer
    return abs(a-b);
}

所以基本上我想做的是通過使用mod 2的簡單方法來轉換其二進制表示形式的整數。然后執行一個任務,以其二進制表示形式從左到右找到第一個1,並且指針位於第一個數。 現在,使用第一個1的索引來計算奇數和偶數位置1的數目。最后返回總的偶數和奇數位置1的絕對差。

一種簡單的方法:

#include <stdint.h>
int absdiffevenoddpopcount(uint64_t x) {
    uint64_t a = x &  0x5555555555555555;
    uint64_t b = x & ~0x5555555555555555;
    while(a && b) {
        a &= a - 1;
        b &= b - 1;
    }
    x = a ? a : b;
    int r = 0;
    while(x) {
        x &= x - 1;
        r++;
    }
    return r;
}

無論如何,此頁面收集了此類位黑客: https : //graphics.stanford.edu/~seander/bithacks.html

同樣,某些處理器具有特殊的指令,對於(位數)人口計數而言,它們可能會更快,通常編譯器會將其作為內置函數提供給C。

基本上,您可以使用&保留僅奇數和偶數位。 您可以同時對兩個數字進行計數,最后返回差值。 所以:

long long int F(long long int k)
{
     long long int odds, evens;
     odds = k & 0x5555555555555555;
     evens = k & 0xaaaaaaaaaaaaaaaa;
     return abs( __builtin_popcountll(odds) -  __builtin_popcountll(evens));
}

我用gcc bultin popcount寫的。 如果使用其他編譯器,則可以在其手冊中找到它。

更加C ++友好的版本:

int F(long long const k) {
  return std::abs(static_cast<int>(std::bitset<64>(k & 0x5555555555555555).count()) - 
                  static_cast<int>(std::bitset<64>(k & 0xaaaaaaaaaaaaaaaa).count()));
}

現場演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM