[关闭]
@geek-sjl 2018-10-22T03:57:18.000000Z 字数 1995 阅读 408

simple division

递归版本

  1. #include <cstdio>
  2. struct res{
  3. long long q;
  4. long long r;
  5. };
  6. struct res divide_t(long long divided,long long divisor){
  7. struct res zeroRes;
  8. zeroRes.q=0;zeroRes.r=0;
  9. if(divided==0) return zeroRes;
  10. struct res tmpRes_t=divide_t(divided>>1,divisor);
  11. tmpRes_t.q<<=1;
  12. tmpRes_t.r<<=1;
  13. if(divided&1) tmpRes_t.r++;
  14. if(tmpRes_t.r>=divisor){
  15. tmpRes_t.r-=divisor;
  16. tmpRes_t.q++;
  17. }
  18. return tmpRes_t;
  19. }
  20. int divide(long long divided,long long divisor){
  21. //if(divisor==0||(divided==INT_MIN&&divisor==-1)) return INT_MAX;
  22. bool isNegative=false;
  23. if(divided<0) {isNegative=!isNegative;divided=-divided;}
  24. if(divisor<0) {isNegative=!isNegative;divisor=-divisor;}
  25. struct res tmpRes_t=divide_t(divided,divisor);
  26. if(isNegative) return -tmpRes_t.q;
  27. else return tmpRes_t.q;
  28. }
  29. int main(){
  30. int divided,divisor;
  31. scanf("%d%d",&divided,&divisor);
  32. printf("%d\n",divide(divided,divisor));
  33. }

emmm...基本上就是照着slide的代码翻译一下。
说一下理解吧。
1. 关于递归的临界条件,除数为0就返回0..emmm没毛病。
2. 递归下一层的时候除数除于2,被除数不变,再把结果翻倍。这个也好理解,


3. 然后是递归调用前的divided为奇数,那么位移操作会把尾数舍去,再余数部分加回即可
4. 最后判断余数和被除数的关系,返回最后结果。

看完代码有种感觉是:这都能得出结果?分析一下好像又没有哪里不对..颠覆常识了2333
还有一个,leetcode交的时候没有注意数据范围..abs后溢出了T.T

迭代版本

  1. #include <cstdio>
  2. using namespace std;
  3. typedef long long LL;
  4. int divide(LL divided,LL divisor){
  5. //if(divisor==0||(divided==INT_MIN&&divisor==-1)) return INT_MAX;
  6. bool isNegative=false;
  7. if(divided<0) {isNegative=!isNegative;divided=-divided;}
  8. if(divisor<0) {isNegative=!isNegative;divisor=-divisor;}
  9. if(divided==0) return 0;
  10. LL q=0,r=0;
  11. LL tmpDivided=0;
  12. int count=0;
  13. int countAll=0;
  14. LL toCountBit=divided;
  15. //计算一共有多少位
  16. while(toCountBit>0){
  17. toCountBit>>=1;
  18. countAll++;
  19. }
  20. //printf("%d\n",countAll);
  21. while(tmpDivided<divided){
  22. tmpDivided<<=1;
  23. //因为要从最高位开始计算,所以要1<<(countAll-count-1)
  24. if((1<<(countAll-count-1))&divided){
  25. tmpDivided++;
  26. }
  27. q<<=1;
  28. r<<=1;
  29. if(tmpDivided&1) r++;
  30. if(r>=divisor){
  31. q++;
  32. r-=divisor;
  33. }
  34. count++;
  35. }
  36. if(isNegative) return -q;
  37. else return q;
  38. }
  39. int main(){
  40. int divided,divisor;
  41. scanf("%d%d",&divided,&divisor);
  42. printf("%d\n",divide(divided,divisor));
  43. }

改写的思路就是把自顶向下改成自底向上,emmmm..先从递归的临界条件开始,逐步往上推,思路是不变的。leetcode交了一下过了,应该没有问题(如果它的数据不水的话)。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注