zoukankan      html  css  js  c++  java
  • 循环小数与无限不循环小数

     从键盘输入分子b和分母a,判断该分数(真分数)是否是无限循环小数,并给出循环开始出现的位数。验证如下结论是否正确:

    (对于分数b/a,小数点至多a位, 或a位之内开始出现无限循环。)

     例如:

     3/8 = 0.375  //小数点不超过7位(有限小数)

     1/3 = 0.333333...//从1位开始出现无限循环

     1/7 = 0.142857 142857 142857 //6位开始(7位内)出现循环序列:142857 

     6/7 = 0.857142 857142 857142 //6位开始(7位内)出现循环序列:857142

    (试试神奇的分数1/49和100/9801,100/9899)

    提示:

     假设分数是3/8=0.375

     小数第1位上的数字是30/8的商,就是表达式30/8的值:3

     30%8(求余)的值是6,那么 小数第2位上的数字是60/8的值:7

     60%8(求余)的值是4,那么,小数第3位上的数字是40/8的值:5

    再写的过程中遇到很多问题,逐一解决,所以在代码中可能有些复杂不够精简,限于作者水平。。。。。

    此题必然还有更为简便的方案,下次想出来再改;

    首先利用题目所给方法求出其小数部分,然后我的想法是取出 2a 个小数点后的数字逐一判断;

    但是呢,问题出现在数字重复可能不是循环的,因为他可能就连续出现几个一样的数字;

    这个问题困扰了很久,最后解决的方案不太理想,但也能解决;

    其他的循环与不循环相对较容易;

    代码如下:

     1 #include <iostream>
     2 using namespace std;
     3 
     4 int  main()
     5 {
     6     int b,a;
     7     cin>>b>>a;
     8     int arr[a*2+1] ,i,j,k,temp,m,n;
     9     int sign,sum = 0;
    10     temp = b;
    11     for(i = 1; i <= a*2; i++)        // 2a位小数 
    12     {
    13          temp *= 10;
    14          arr[i] = temp / a;
    15          temp %= a;
    16 //         cout<<arr[i]; 
    17          if(i>a)
    18              sum += arr[i];
    19     }
    20     if(sum == 0)
    21         cout<<"该分数为有限小数"<<endl;
    22     else
    23     {
    24         for(i = 1;i <= 2*a;i++)
    25         {
    26             for(j = 1;j < i;j++)        // 有相等 
    27             {
    28                 if(arr[i] == arr[j])        
    29                 {
    30                     sign = 0;
    31                     m = i-j;            // 循环位数 
    32                     if(m != 1)            // 必为不相同循环   2 329
    33                     {
    34                         for(k = 1;k < a;k++)         // 保证中间无小段循环 
    35                             if(arr[i+k] != arr[j+k])
    36                                 sign++;
    37                     } 
    38                     else        // 必为相同循环 
    39                     {
    40                         for(k = 1;k <= a - j;k++)    
    41                             if(arr[j] != arr[j+k])
    42                                 sign++;
    43                     }        
    44                 }
    45                 if(sign == 0)            // 确定为循环 
    46                 {
    47                     n = i - 1;        // 起始循环点 
    48                     break;
    49                 }            
    50             }
    51             if(sign == 0)
    52                 break;        
    53         }
    54         if(sign == 0)
    55             cout<<"该分数为无限循环小数,循环位数:"<<n<<endl;
    56         else
    57             cout<<"该分数为无限不循环小数"<<endl;            
    58     }   
    59     return 0;
    60 } 

    测试例子:

    3 8

    1 3

    1 7

    1 49

    输出:

    该分数为有限小数

    该分数为无限循环小数,循环位数:1

    该分数为无限循环小数,循环位数:6

    该分数为无限循环小数,循环位数:42

     

    2020-01-1115:35:53

  • 相关阅读:
    [Tips] 树莓派VNC登录
    [Tips] 联通宽带+华为路由器,如何进行NAT
    [Tips] 树莓派4B 风扇安装
    [Tips] 家庭树莓派,如何外网访问
    [Tips] 命令行获取设备的外网IP
    MySQL 如何让自增id设置为从1开始
    MySQL报错:Packet for query is too large (2,588 > 2,048).
    Java 实现 Timstamp 和 String 互相转换
    MySQL修改 mysql-bin 日志保存天数以及文件大小限制
    Linux Shell 中的年月日 时分秒
  • 原文地址:https://www.cnblogs.com/2015-16/p/12180070.html
Copyright © 2011-2022 走看看