zoukankan      html  css  js  c++  java
  • No.29 Divide Two Integers

    No.29 Divide Two Integers

    Divide two integers without using multiplication, division and mod operator.

    If it is overflow, return MAX_INT.

     Tags: Math Binary Search

      计算dividend/divisor,不能用乘法、除法和模运算符
      如果溢出,返回MAX_INT
      误区:除法,得到结果仍为整数,其实就是dividend = n * divisor + b;别想得,太复杂
      疑问:什么时候会溢出呢?
      因为计算时,要将负数转为整数进行运算,所以-INT_MIN是会溢出的
       另外,MAX_INT/-1 会溢出(注意正负范围的那点儿差异)
      分析:
        不能用乘、除和取模,那剩下的,还有加、减和位运算。
        最简单的方法,是不断减去被除数。在这个基础上,可以做一点优化,每次把被除数翻倍,从而加速

        即,对a/b来说,a-b-2b-4b-8b...,翻倍就是移位操作

     
     1 #include "stdafx.h"
     2 #include <string>
     3 #include <iostream>
     4 #include <unordered_map>
     5 
     6 using namespace std;
     7 
     8 
     9 class Solution
    10 {
    11 public:
    12     int divide(int dividend, int divisor)
    13     {
    14     /*
    15         计算dividend/divisor,不能用乘法、除法和模运算符
    16         如果溢出,返回MAX_INT
    17         误区:除法,得到结果仍为整数,其实就是dividend = n * divisor + b;别想得,太复杂
    18         疑问:什么时候会溢出呢?
    19               因为计算时,要将负数转为整数进行运算,所以-INT_MIN是会溢出的
    20               另外,MAX_INT/-1 会溢出(注意正负范围的那点儿差异)
    21         分析:
    22             不能用乘、除和取模,那剩下的,还有加、减和位运算。
    23             最简单的方法,是不断减去被除数。在这个基础上,可以做一点优化,每次把被除数翻倍,从而加速
    24         参考:书
    25     */
    26         // 当 dividend = INT_MIN 时,-dividend 会溢出,所以用 long long!!!
    27         if(divisor == 0)
    28             return INT_MAX;//返回这个吗?看题意吧
    29         if(dividend == 0)
    30             return 0;
    31 
    32         long long a = dividend>0 ? dividend : -(long long)dividend;
    33         long long b = divisor>0 ? divisor : -(long long)divisor;
    34 
    35         // 当 dividend = INT_MIN 时,divisor = -1 时,结果会溢出,所以用 long long!!!
    36         long long result = 0;
    37         while( a >= b)
    38         {
    39             long long c = b;
    40             for(int i=0; a >=c ; ++i,c <<= 1)
    41             {
    42                 a -= c;//a每次减2^i*c
    43                 result += 1<<i;//result每次加2^i
    44             }
    45         }
    46 //        return ((dividend^divisor) >> 31) ? (-result) : result;//异或+移位,判断符号位!!!巧妙,两种方法都可以
    47         if((dividend<0) ^ (divisor<0))
    48             result = -result;
    49 //        if((dividend^divisor) >> 31)
    50 //            result = -result;
    51         if(result > INT_MAX || result < INT_MIN)
    52             return INT_MAX;
    53         return result;
    54     }
    55 };
    56 
    57 
    58 int main()
    59 {
    60     Solution sol;
    61 
    62     cout  <<" : "<< sol.divide(INT_MIN, -1)<<endl;//终极大挑战
    63     return 0;
    64 }

      另外有一种方法应该也可以,但没有理解,觉得没有这种方法简单易懂些,参见:http://blog.csdn.net/linhuanmars/article/details/20024907

  • 相关阅读:
    精选 TOP 面试题
    leecode100热题 HOT 100(2)
    leecode100热题 HOT 100
    leetcode题库
    LeetCode All in One 题目讲解汇总(持续更新中...)
    LVS负载均衡(LVS简介、三种工作模式、十种调度算法)
    Smart/400开发上手3: 练习实践
    Smart/400开发上手2: COBOL批处理程序处理过程
    Smart/400开发上手1:入门
    一步步Cobol 400上手自学入门教程06
  • 原文地址:https://www.cnblogs.com/dreamrun/p/4538529.html
Copyright © 2011-2022 走看看