zoukankan      html  css  js  c++  java
  • Leetcode 166. Fraction to Recurring Decimal 弗洛伊德判环

    分数转小数,要求输出循环小数 如2 3 输出0.(6)

    弗洛伊德判环的原理是在一个圈里,如果一个人的速度是另一个人的两倍,那个人就能追上另一个人。代码中one就是速度1的人,而two就是速度为2的人。

    Fraction to Recurring Decimal可以使用弗洛伊德判环,不同的是要找到循环出现的起始点,因此会比单单判断是否循环出现的题要难一点,代码要长一点,但是它比是用map的实现会更快。

    要做出这道题有几个注意点:

    1)对于整数的求余和整除运算要注意,特别负数的求余运算, 可以参考 getMode_()和getShang_();

    2) 由于整数整除的特殊性,对于整数整除是0的无法判断正负,因此要转化成double再判断;

    3)对于弗洛伊德判环请注意退出条件和找到循环出现的起始点和结束点,注意初始化。

     1 class Solution {
     2 public:
     3     typedef long long __int64;
     4        inline __int64 getShang_(__int64 numerator, __int64 denominator){//特别注意数字都要取绝对值
     5         return abs(numerator) / abs(denominator);
     6     }
     7 
     8     inline __int64 getMod_(__int64 numerator, __int64 denominator){//特别注意数字都要取绝对值
     9         return abs(numerator) % abs(denominator);
    10     }
    11 
    12     inline std::string inttostr_(__int64 num){
    13         char t[20] = { 0 };
    14          sprintf(t, "%lld", num);
    15         return std::string(t);
    16     }
    17 
    18     std::string fractionToDecimal(int numerator, int denominator) {
    19         std::string Integer_("");
    20         if ((double)numerator / denominator < 0) Integer_ = "-"; //整数整除是0的无法判断正负
    21         Integer_ += inttostr_(getShang_(numerator, denominator));
    22         
    23         if (0 == getMod_(numerator,denominator) ) {
    24             return Integer_;
    25         }
    26         Integer_ += ".";
    27         __int64 tnumerator = numerator;
    28         tnumerator = getMod_ (tnumerator, denominator);
    29         //printf("%lld
    ", numerator);
    30         __int64 one = tnumerator;
    31         __int64 two = tnumerator;
    32         std::vector<__int64> vyushu;
    33         std::string Decimal_("");
    34         vyushu.push_back(two);
    35         int cnt = 0;  //循环节周期
    36         while (true)
    37         {
    38             one = getMod_(one * 10, denominator);
    39             
    40             Decimal_ += inttostr_(getShang_(two * 10, denominator));
    41             two = getMod_(two * 10, denominator);
    42             vyushu.push_back(two);
    43             if (0 == two) break;//退出条件
    44 
    45             Decimal_ += inttostr_(getShang_(two * 10, denominator));
    46             two = getMod_(two * 10, denominator);
    47             vyushu.push_back(two);
    48             if (0 == two) break;//退出条件
    49 
    50             cnt++;
    51             if (two == one) break;
    52         }
    53         /*for (auto i:vyushu){
    54             std::cout << i << std::endl;
    55         }
    56         std::cout << Decimal_ << std::endl;
    57         std::cout << cnt << std::endl;*/
    58         if (two){     //找到循环出现的起始点和结束点[j,k)
    59             int j = 0, k = 0;
    60             for (std::vector<int>::size_type i = vyushu.size()-1; i >= 0&& i>=cnt; --i){
    61                 if (vyushu[ i -cnt] != vyushu[ i]){
    62                     j = i - cnt + 1;
    63                     break;
    64                 }
    65             }
    66             for (std::vector<int>::size_type i = j + 1; i < vyushu.size(); ++i){
    67                 if (vyushu[i] == vyushu[j]) {
    68                     k = i;
    69                     break;
    70                 }
    71             }
    72             //std::cout << j << " " << k << std::endl;
    73             return  Integer_ + Decimal_.substr(0, j) + "(" + Decimal_.substr(j, k - j) +")";
    74         }
    75         else return Integer_ + Decimal_;
    76         
    77     }
    78 };

    在代码中注释部分出现的某些代码是来自c++11标准的,请忽略! 另外c++11标准直接支持__int64。

  • 相关阅读:
    你不能忽视的HTML代码2精编篇
    C#中析构函数和命名空间的妙用
    值类型和引用类型及其它
    这些年我收集的GDI+代码2
    C#中超级好用的字符串
    Javascript的压缩优化
    Spring和hibernate多个数据源的事务管理
    android中Handler,Looper,Message的开发答疑
    Spring引用Tomcat的 JTA事务
    js禁止用户刷新页面
  • 原文地址:https://www.cnblogs.com/onlyac/p/5126517.html
Copyright © 2011-2022 走看看