zoukankan      html  css  js  c++  java
  • leetcode 29两数相除

    我理解本题是考察基于加减实现除法,代码如下:

    class Solution {
    public:
        //只用加减号实现除法,
        //不用加减号实现除法;
        int divide(int dividend, int divisor) {
        //
            if(dividend==INT_MIN&&divisor==-1){
                return INT_MAX;
            }
            long dvd=labs(dividend);long dvs=labs(divisor);long ans=0;
            int sign=dividend^divisor;
            for(int i=31;i>=0;i--){
                if((dvd>>i)>=dvs){
                    dvd-=dvs<<i;
                    ans+=1<<i;
                }
            }
            if(sign<0)
                ans=-ans;
            return ans;
        }
    
    };

     如果单纯基于位运算呢?加减也依靠位运算如何避免溢出?

    以下为不使用“+ - * / ”四个符号完成计算:

    class Solution {
    public:
        //只用加减号实现除法,
        //不用+ - * / 实现除法;
        const int minus_one=substract(0,1);
        int divide(int dividend, int divisor) {
            if (dividend == INT_MIN && divisor == minus_one) {
                return INT_MAX;
            }
            long dvd = long(dividend<0?add(~dividend,1):dividend), dvs = long(divisor<0?add(~divisor,1):divisor), ans = 0;
            if(dividend==INT_MIN) dvd=2147483648;
            if(divisor==INT_MIN) dvs=2147483648;
            /**test for some cases
            cout<<dvd<<","<<dvs<<endl;
            cout<<labs(dvd)<<","<<labs(dvs)<<endl;
            cout<<add(~divisor,1); **/
            
            int sign = dividend > 0 ^ divisor > 0 ? minus_one : 1;
            while (dvd >= dvs) {
                long temp = dvs, m = 1;
                while (temp << 1 <= dvd) {
                    temp <<= 1;
                    m <<= 1;
                }
                dvd =substract(dvd,temp);
                ans =add(ans,m);
            }
            return sign>0?ans:substract(0,ans);
        }
        int add(int a,int b){
            long long carry=b;
            while(b!=0){
                carry=a&b;
                a=a^b;
                b=(carry&0xffffffff)<<1;//避免负数左移溢出
            }
            return a;
        }
        int substract(int a,int b){
            int c=add(~b,1);
            int res=add(a,c);
            return res;
        }
    };
  • 相关阅读:
    简单区分Vmware的三种网络连接模式(bridged、NAT、host-only)
    linux创建账户并自动生成主目录和主目录下的文件
    EF 通用数据层类
    html在线美化网站
    图片在页面中居中显示
    __dopostback的用法
    rdlc报表集锦
    .NET开源免费的功能强大控件库
    使用webclient上传下载实例
    消息队列将并发变串行
  • 原文地址:https://www.cnblogs.com/joelwang/p/10949221.html
Copyright © 2011-2022 走看看