找数据二进制长度

问题

       在osc上看到一个提问

       输入一个数据,求该数据转换为2进制后的长度,譬如10 -> 1010,长度为4 。

        问题传送门:http://www.oschina.net/question/122712_158916

代码

二分查找

 开销为 O(log(sizeof(T) * 8)), T 为数据类型

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>

using namespace std;
template<typename T>
class bitLenQuery{
    public:
        bitLenQuery(void): posTable(NULL), bitLen(sizeof(T) * 8){}
        int createTable(void);
        int getLen(const T &keyVal);
        virtual ~bitLenQuery(void);
    private:
        void destoryTable(void);
        int *posTable;
        int bitLen;
};

template <typename T>
int bitLenQuery<T>::createTable(void){
    posTable = new int[bitLen];
    if(!posTable){
        return -1;
    }
    for(int currPos = 0; currPos < bitLen; currPos++){
                posTable[currPos] = 1 << currPos;
    }
    return 0;
}

template <typename T>
void bitLenQuery<T>::destoryTable(void){
    if(posTable)
        delete posTable;
}

template<typename T>
bitLenQuery<T>::~bitLenQuery(void){
    destoryTable();
    posTable = NULL;
    bitLen = 0;
}

template<typename T>
int bitLenQuery<T>::getLen(const T &keyVal)
{
    if( keyVal == (T)0){
        return 0;
    }
    if( keyVal & posTable[bitLen - 1]){
        return bitLen;
    }
    int lftPos = 0;
    int rhtPos = bitLen - 1;
    while(lftPos <= rhtPos){
            int midPos = ((rhtPos - lftPos) >> 1) + lftPos;
            if( keyVal == posTable[midPos]){
                    return (midPos + 1);
            }
            if( (keyVal > posTable[midPos]) && ( keyVal < (posTable[midPos] << 1)) ){
                    return (midPos + 1);
            }
            if(keyVal < posTable[midPos]){
                    rhtPos = midPos - 1;
            }
            if(keyVal > posTable[midPos]){
                    lftPos = midPos + 1;
            }
    }
    return -1;
}

直接使用math库

log(n) + 1

暴力求解

int bit_len(unsigned int n){
if(n>0x7fffffff)return 32;

if(n>0x3fffffff)return 31;
if(n>0x1fffffff)return 30;


if(n>0xfffffff)return 29;
if(n>0x7ffffff)return 28;
if(n>0x3ffffff)return 27;
if(n>0x1ffffff)return 26;


if(n>0xffffff)return 25;
if(n>0x7fffff)return 24;
if(n>0x3fffff)return 23;
if(n>0x1fffff)return 22;


if(n>0xfffff)return 21;
if(n>0x7ffff)return 20;
if(n>0x3ffff)return 19;
if(n>0x1ffff)return 18;


if(n>0xffff)return 17;
if(n>0x7fff)return 16;
if(n>0x3fff)return 15;
if(n>0x1fff)return 14;


if(n>0xfff)return 13;
if(n>0x7ff)return 12;
if(n>0x3ff)return 11;
if(n>0x1ff)return 10;


if(n>0xff)return 9;
if(n>0x7f)return 8;
if(n>0x3f)return 7;
if(n>0x1f)return 6;


if(n>0xf)return 5;
if(n>0x7)return 4;
if(n>0x3)return 3;
if(n>0x1)return 2;


if(n>0x0)return 1;
return 0;
}

粗犷二分

int bit_len(unsigned int n){
 if(n>0xffff){
  if(n>0xffffff){
   if(n>0x7fffffff)return 32;
   if(n>0x3fffffff)return 31;
   if(n>0x1fffffff)return 30;
   if(n>0xfffffff)return 29;
   if(n>0x7ffffff)return 28;
   if(n>0x3ffffff)return 27;
   if(n>0x1ffffff)return 26;
   return 25;
  }else{
   if(n>0x7fffff)return 24;
   if(n>0x3fffff)return 23;
   if(n>0x1fffff)return 22;
   if(n>0xfffff)return 21;
   if(n>0x7ffff)return 20;
   if(n>0x3ffff)return 19;
   if(n>0x1ffff)return 18;
   return 17;
  }
 }else{
  if(n>0xff){
   if(n>0x7fff)return 16;
   if(n>0x3fff)return 15;
   if(n>0x1fff)return 14;
   if(n>0xfff)return 13;
   if(n>0x7ff)return 12;
   if(n>0x3ff)return 11;
   if(n>0x1ff)return 10;
   return 9;
  }else{
   if(n>0x7f)return 8;
   if(n>0x3f)return 7;
   if(n>0x1f)return 6;
   if(n>0xf)return 5;
   if(n>0x7)return 4;
   if(n>0x3)return 3;
   if(n>0x1)return 2;
   if(n>0x0)return 1;
  }
 }
 return 0;
}

参考文章

http://www.oschina.net/question/122712_158916

更多

       求指点,有没常数级的求解法啊,能在O(1)做出如下转换么?(二进制表示)

1010   -> 1000
110    -> 100
100101 -> 100000


       


你可能感兴趣的:(bit长度)