• Divide Two Integers


    零. 例行废话

      这个问题其实很早了,也没什么特别tricky的地方,但是我今天突然做到这道题,发现竟然博客上竟然没有比较靠谱的解法,要么大家就是用笨重的累减法,要么就是不要face的公然用除法。关于溢出处理,我发现基本上都没有遵循题目中说的$[ - {2^{31}},{2^{31}} - 1]$的约定,用了long或者long long,实在是太bitch了,有必要由我给大家提供一种比较靠谱的方法。

    一. 问题重述

    大家先读题,圈重点,显然这个题有两个重要的地方:

    1. 不用乘除模实现除法

    2. 只能使用32-bit int,也就是要避免溢出

    二. bitch的做法

    我在提交的时候,随便打开几个答案,发现大家要么是在溢出上做手脚,像这样:

    要么是更加猖狂的公然用除法:

    三. 正经人的做法

      其实仔细考虑这个问题,并不是很复杂,主要要解决两个方面的问题,最重要的要找到一种除法的替代方法,一个比较直观的做法是把除法转化为减法,但是我们考虑到这样子做效率太低,交上去怕是要被time out

      考虑一种高效的,有一定乘法效应的移位算法,我们可以通过不断用移位操作去逼近被除数,然后对余数再进行指数逼近,这样做就很高效了。

            对于溢出,我觉得可以从两个方面来考虑:

    •   将所有的操作数都转化为负数,因为负数范围大
    •   在移位的时候及时与-2^30进行比较,以免下次移位溢

    四. 源码

    using namespace std;
    
    class Solution {
    public:
        int divide_(int dividend, int divisor) {
            int divisor_copy = divisor;
            int k = 0;
            while(true){
                int number = (divisor_copy << k);
                if(number >= dividend){
                    k ++;
                    if(number < (-2 << 29)){
                        break;
                    }
                }else{
                    break;
                }
            }
           // cout << k << endl;
            if(k == 0){
                return 0;
            }
            if(k == 1){
                return -1 + divide_(dividend - divisor , divisor);
            }
            return (-2 << (k - 2)) + divide_(dividend - (divisor << (k - 1)), divisor);
        }
        int divide(int dividend, int divisor){
            bool flag = true;
            bool f1 = true, f2 = true;
            if(dividend > 0){
                f1 = false;
                dividend = - dividend;
            }
            if(divisor > 0){
                f2 = false;
                divisor = - divisor;
            }
            if(f1 != f2)
                flag = false;
            int result = divide_(dividend, divisor);
            if(flag){
                if(result == (-2 << 30)){
                    return -(result + 1);
                }else{
                    return -result;
                }
            }
            else
                return result;
        }
    };

    五. 一个奇怪的事情

      我发现一个最最最奇怪的事情是我的很长很长的代码竟然比直接使用除法的快了一倍,难道说我的代码已经突破底层的计算效率了么(伪),见下图:

       

  • 相关阅读:
    零基础学python-2.7 列表与元组
    什么是App加壳,以及App加壳的利与弊
    Linux tar包安装Nginx
    GT背靠背onsite
    编程算法
    DELPHI动态创建窗体
    扩展名为DBF的是什么文件啊?
    异构数据库之间完全可以用SQL语句导数据
    XP局域网访问无权限、不能互相访问问题的完整解决方案
    Delphi 之 菜单组件(TMainMenu)
  • 原文地址:https://www.cnblogs.com/sugar-mouse-wbz/p/9911786.html
Copyright © 2020-2023  润新知