Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 计数1';二进制表示中的s_Algorithm_Binary - Fatal编程技术网

Algorithm 计数1';二进制表示中的s

Algorithm 计数1';二进制表示中的s,algorithm,binary,Algorithm,Binary,如果你有足够的内存可以玩的话,在O(1)中一个数字的二进制表示法中计算1的有效方法。这是我在一个在线论坛上发现的一个面试问题,但没有答案。有人能给我提个建议吗?我想不出一个办法能在一(1)分钟内做到这一点。这将是我一生中最短的答案:查阅表格。 显然,我需要解释一下:“如果你有足够的内存玩”意味着,我们已经拥有了所有我们需要的内存(不管技术上的可能性有多大)。现在,您不需要存储超过一两个字节的查找表。虽然从技术上讲它是Ω(log(n))而不是O(1),但只要读取一个你需要的数字就是Ω(log(n)

如果你有足够的内存可以玩的话,在O(1)中一个数字的二进制表示法中计算1的有效方法。这是我在一个在线论坛上发现的一个面试问题,但没有答案。有人能给我提个建议吗?我想不出一个办法能在一(1)分钟内做到这一点。

这将是我一生中最短的答案:查阅表格。

显然,我需要解释一下:“如果你有足够的内存玩”意味着,我们已经拥有了所有我们需要的内存(不管技术上的可能性有多大)。现在,您不需要存储超过一两个字节的查找表。虽然从技术上讲它是Ω(log(n))而不是O(1),但只要读取一个你需要的数字就是Ω(log(n)),所以如果这是个问题,那么答案是,不可能——甚至更短

没人知道他们希望你在面试中给出哪两个答案

还有另一个窍门:工程师们可以拿一个数字来讨论Ω(log(n)),其中n是数字,计算机科学家会说,实际上我们要测量运行时间,作为输入长度的函数,所以工程师们称之为Ω(log(n))的实际上是Ω(k),其中k是字节数。不过,正如我之前所说,仅仅读取一个数字就是Ω(k),因此我们没有办法做得比这更好。

这就是问题所在,即人口计数。链接提到了高效的实现。引述:

有了无限的内存,我们可以简单地创建一个大的查找表,其中包含每个64位整数的汉明权重


我有一个解决方案,可以计算
O(1的数量)
时间中的位:

bitcount(n):
    count = 0
    while n > 0:
        count = count + 1
        n = n & (n-1)
    return count
在最坏的情况下(当数字为2^n-1时,所有1都是二进制的),它将检查每一位

编辑: 刚刚发现了一个非常好的恒定时间、恒定内存位计数算法。这是用C写的:

int BitCount(unsigned int u)
{
     unsigned int uCount;

     uCount = u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111);
     return ((uCount + (uCount >> 3)) & 030707070707) % 63;
}

你可以找到它正确性的证明。

我能想到的只有一种方法可以在O(1)中完成这项任务。。。也就是说“欺骗”并使用物理设备(对于线性或甚至并行编程,我认为限制是O(log(k)),其中k表示数字的字节数)

然而,您可以很容易地想象一个物理设备,它用0/1电压将每一位连接到输出线。然后你可以通过电子方式读取O(1)中“求和”线上的总电压。很容易使这个基本思想更优雅,一些基本电路元件以任何形式产生输出(例如二进制编码输出),但基本思想是相同的,电子电路将在固定时间内产生正确的输出状态


我想也可能有量子计算的可能性,但如果允许我们这样做,我会认为简单的电子电路是更容易的解决方案。

我实际上使用了一点技巧:一个包含16个条目的单一查找表就足够了,你所要做的就是将二进制rep分解成半字节复杂度实际上是O(1),我写了一个C++模板,它专门针对你想要的整数的大小(在……位中)……使它成为一个常量表达式而不是不确定的。 fwiw您可以使用(i&-i)将返回LS一位,然后简单地循环,每次剥离lsbit,直到整数为零,但这是一个旧的奇偶校验技巧。

publicstaticvoidmain(String[]args){
public static void main(String[] args) {

    int a = 3;
    int orig = a;
    int count = 0;
    while(a>0)
    {
        a = a >> 1 << 1;
        if(orig-a==1)
            count++;
        orig = a >> 1;
        a = orig;
    }

    System.out.println("Number of 1s are: "+count);
}
INTA=3; int-orig=a; 整数计数=0; 而(a>0) { a=a>>1>1; a=原始值; } System.out.println(“1的数量为:“+计数”); }
该函数接受一个
int
并以二进制表示返回一个数

public static int findOnes(int number)
{

   if(number < 2)
    {
        if(number == 1)
        {
            count ++;
        }
        else
        {
            return 0;
        }
    }

    value = number % 2;

    if(number != 1 && value == 1)
        count ++;

    number /= 2;

    findOnes(number);

    return count;
}
公共静态整数findOnes(整数编号)
{
如果(数字<2)
{
如果(数字==1)
{
计数++;
}
其他的
{
返回0;
}
}
值=数字%2;
if(number!=1&&value==1)
计数++;
数目/=2;
芬顿(数字);
返回计数;
}

我在另一个网站上看到了以下解决方案:

int count_one(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;
}

下面也可以

nofone(int x) {
  a=0;
  while(x!=0) {
    x>>=1;
    if(x & 1)
      a++;
  }
  return a;
} 

请注意:n&(n-1)总是消除最不重要的1

因此,我们可以编写计算1个数的代码,如下所示:

count=0;
while(n!=0){
  n = n&(n-1);
  count++;
}
cout<<"Number of 1's in n is: "<<count;
private static int countBits(int number)    {
    boolean negFlag = false;
    if(number < 0)  { 
        negFlag = true;
        number = ~number;
    }

    int result = 0;
    while(number != 0)  {
        result += number & 1;
        number = number >> 1;
    }
    return negFlag? (32-result): result;
}
count=0;
而(n!=0){
n=n&(n-1);
计数++;
}

我来到这里,坚信我知道这个问题的完美解决方案。C代码:

    short numberOfOnes(unsigned int d) {
        short count = 0;

        for (; (d != 0); d &= (d - 1))
            ++count;

        return count;
    }
但在我对这个主题做了一些研究(阅读其他答案:)之后,我发现了5种更有效的算法。我爱死你了

甚至还有专门为此任务设计的CPU指令:
popcnt
。 (中提到)


您可以找到的许多算法的描述和基准测试。

以下是使用位运算符的C解决方案:

int numberOfOneBitsInInteger(int input) {
  int numOneBits = 0;

  int currNum = input;
  while (currNum != 0) {
    if ((currNum & 1) == 1) {
      numOneBits++;
    }
    currNum = currNum >> 1;
  }
  return numOneBits;
}
以下是使用2次幂的Java解决方案:

public static int numOnesInBinary(int n) {

  if (n < 0) return -1;

  int j = 0;
  while ( n > Math.pow(2, j)) j++;

  int result = 0;
  for (int i=j; i >=0; i--){
    if (n >= Math.pow(2, i)) {
        n = (int) (n - Math.pow(2,i));
        result++;    
    }
  }

  return result;
}
公共静态int numOnesInBinary(int n){
如果(n<0)返回-1;
int j=0;
而(n>Math.pow(2,j))j++;
int结果=0;
对于(int i=j;i>=0;i--){
如果(n>=数学功率(2,i)){
n=(int)(n-Math.pow(2,i));
结果++;
}
}
返回结果;
}

在python或任何其他转换为bin字符串中,然后使用“0”将其拆分以除去0,然后合并并获得长度

len(''.join(str(bin(122011)).split('0')))-1

就这样?

下面的方法也可以计算负数中的1数

private static int countBits(int number)    {
    int result = 0;
    while(number != 0)  {
        result += number & 1;
        number = number >>> 1;
    }
    return result;
}
然而,像-1这样的数字在二进制中表示为11111111111111111111,因此需要大量移位。如果您不想对小负数执行如此多的轮班,另一种方法可以如下所示:

count=0;
while(n!=0){
  n = n&(n-1);
  count++;
}
cout<<"Number of 1's in n is: "<<count;
private static int countBits(int number)    {
    boolean negFlag = false;
    if(number < 0)  { 
        negFlag = true;
        number = ~number;
    }

    int result = 0;
    while(number != 0)  {
        result += number & 1;
        number = number >> 1;
    }
    return negFlag? (32-result): result;
}
私有静态int countBits(int number){
布尔NEGFALG=false;
如果(数<0){
negFlag=true;
number=~number;
}
int结果=0;
while(数字!=0){
结果+=数字&1;
数字=数字>>1;
}
返回negFlag?(32结果):
0b1111011.toString(2).replace("0","").length  // returns 6
l=->x{x.to_s(2).count ?1}
def find_consecutive_1(n)
  num = n.to_s(2)
  arr = num.split("")
  counter = 0
  max = 0
  arr.each do |x|
      if x.to_i==1
          counter +=1
      else
          max = counter if counter > max
          counter = 0 
      end
      max = counter if counter > max  
  end
  max
end

puts find_consecutive_1(439)
/* Method-1 */
int count1s(long num)
{
    int tempCount = 0;

    while(num)
    {
        tempCount += (num & 1); //inc, based on right most bit checked
        num = num >> 1;         //right shift bit by 1
    }

    return tempCount;
}

/* Method-2 */
int count1s_(int num)
{
    int tempCount = 0;

    std::string strNum = std::bitset< 16 >( num ).to_string(); // string conversion
    cout << "strNum=" << strNum << endl;
    for(int i=0; i<strNum.size(); i++)
    {
        if('1' == strNum[i])
        {
            tempCount++;
        }
    }

    return tempCount;
}

/* Method-3 (algorithmically - boost string split could be used) */
1) split the binary string over '1'.
2) count = vector (containing splits) size - 1
    int count = 0;

    count = count1s(0b00110011);
    cout << "count(0b00110011) = " << count << endl; //4

    count = count1s(0b01110110);
    cout << "count(0b01110110) = " << count << endl;  //5

    count = count1s(0b00000000);
    cout << "count(0b00000000) = " << count << endl;  //0

    count = count1s(0b11111111);
    cout << "count(0b11111111) = " << count << endl;  //8

    count = count1s_(0b1100);
    cout << "count(0b1100) = " << count << endl;  //2

    count = count1s_(0b11111111);
    cout << "count(0b11111111) = " << count << endl;  //8

    count = count1s_(0b0);
    cout << "count(0b0) = " << count << endl;  //0

    count = count1s_(0b1);
    cout << "count(0b1) = " << count << endl;  //1
function getBinaryValue(num){
 return num.toString(2);
}

function checkOnces(binaryValue){
    return binaryValue.toString().replace(/0/g, "").length;
}