zoukankan      html  css  js  c++  java
  • 大小最接近的那两个数(位操作)

    主要是熟悉位操作,寻找一个数二进制1位相同,且大小最相近的数。

    //题目描述
    //
    //有一个正整数,请找出其二进制表示中1的个数相同、且大小最接近的那两个数。(一个略大,一个略小)
    //给定正整数int x,请返回一个vector,代表所求的两个数(小的在前)。保证答案存在。
    //测试样例:
    //2
    //返回:[1, 4]
    
    //
    //思路:
    //取得略大的数:
    //c0 是拖尾0的个数,c1是紧邻拖尾0左方连续位为1的个数, p为最右边但非拖尾的0 等于 c0 + c1
    //1 把位p置为1
    //2 将p右方所有位置为零  //(1,2的快速做法就是将拖尾0变为1,然后加1)
    //3 在右方插入c1 - 1 个1
    //取得略小的数:
    //1 c1是拖尾1的个数, c0是紧邻拖尾1的左方一连串0的个数,p为最右边但非拖尾的1 等于c0 + c1
    //2 把位p置为0           // (1,2的快速版本就是将拖尾1置为0,然后减1)
    //3 将p右方所以位置清零
    //在p的紧邻右方插入c1 + 1个1
    
    #include <iostream>
    using namespace std;
    #include <vector>
    #include <math.h>
    class CloseNumber{
    public:
        vector<int> getCloseNumber(int x) {
            // write code here
            vector <int> result;
            int c01 = 0;//拖尾0的个数
            int c11 = 0;//拖尾0左方连续全为1的个数
    
            int c1 = 0;//拖尾1的个数
            int c0 = 0;//拖尾1左方全为0的位个数
            int c = x, d = x;//临时变量
            //分别求取max
            while (((c & 1) == 0) && (c != 0)){
                c01++;
                c >>= 1;
            }
            while ((c & 1) == 1){
                c11++;
                c >>= 1;
            }
            //min
            while ((d & 1) == 1){
                c1++;
                d >>= 1;
            }
            while (((d & 1) == 0) && (d != 0)){
                c0++;
                d >>= 1;
            }
    
            result.push_back((x - (1 << (c1)) - (1 << (c0 - 1)) + 1));   //min
            result.push_back((x + (1 << (c11 - 1)) + (1 << c01) - 1));   //max
            return result;
        }
    
         int findNext(int a){
            //c0是尾部0的个数, c1是0左方全为1的个数
            /*
            1,将index位p置为1;
            2,将index位从0到p-1清零
            (1,2的快速做法就是将拖尾0变为1,然后加1)
            3,将index位0到c1-2位置为1
            */
            int c0 = 0, c1 = 0;
            int temp = a;
            while ((temp & 1) == 0 && temp != 0){
                c0++;
                temp >>= 1;
            }
    
            while ((temp & 1) == 1){
                c1++;
                temp >>= 1;
            }
            //判断是否没有更大的数
            if (c0 + c1 == 31 || c0 + c1 == 0){
                return -1;
            }
            int p = c0 + c1;//index为p的位置,此时p的位置肯定是0
            //1,2的快速版
            a += pow(2, c0);  //2^p-2^c1-....
    
            //3,将0到c1-2位置为1
            a += pow(2, c1 - 1) - 1;
            return a;
    
        }
    
         int findPre(int b){
            //c1是尾部1的个数,c0是尾部1左方全为0的个数
            /*
            1,将index位p清零
            2,将p右边所有的位都置为1
            (1,2的快速版本就是将拖尾1置为0,然后减1)
            3,将位0到位c0-2清零
            */
            int c1 = 0, c0 = 0;
            int temp = b;
            while ((temp & 1) == 1){
                c1++;
                temp >>= 1;
            }
            while ((temp & 1) == 0 && temp != 0){
                c0++;
                temp >>= 1;
            }
    
            int p = c0 + c1; //p位肯定为1
            //1,2
            b -= pow(2, c1) - 1;
            b -= 1;
            b -= pow(2, c0 - 1) - 1;
            return b;
        }
    };
    
    int main()
    {
        CloseNumber c;
        vector<int> vc=c.getCloseNumber(14);
        return 0;
    }
  • 相关阅读:
    Rust 变量
    Rust-lang(hello world 续)
    Rust-lang(hello world)
    Java 1.8 ASM ClassReader failed to parse class file
    Sqoop使用笔记
    Jstorm
    从flume到kafka,日志收集
    vim-3-插件管理
    vim-2-使用进阶
    Git-Repo-Gerrit-1-Git介绍,安装和配置
  • 原文地址:https://www.cnblogs.com/ranjiewen/p/5738252.html
Copyright © 2011-2022 走看看