如何计算重复数字?

时间:2008-10-30 05:47:11

标签: algorithm language-agnostic division

给定两个整数ab,我如何计算a / b的重复小数?这可以是任何语言;无论你最简单的表达它。

4 个答案:

答案 0 :(得分:9)

你可以使用你在学校学到的长分算法来计算a / b的十进制表示,正如Mark Ransom所说。要计算每个连续数字,将当前被除数(分子或余数)除以b,并找到下一个被除数为余数乘以10(“降低0”)。如果余数与之前的余数相同,则表示从那时开始的数字也将重复,因此您可以注意到这一事实并停止。

请注意优化的可能性:除以b时得到的余数在0到b-1范围内,因此只保留不同的非零余数,您不必搜索以前的列表留下来看看是否有重复的事情。因此,可以使算法在每个分区步骤中保持恒定时间,并且O(b)空间就足够了。只需跟踪每个剩余首次出现的数字位置。

(这个论点,BTW,也是一个数学证明,重复出现的部分最多可以是b-1位数:例如1/7 = 0.(142857)有一个6位数的重复部分,和1/17 = 0.(0588235294117647)有一个16位数的重复部分。长度总是除以 b-1,实际上。)

以下是执行此操作的Python代码,该代码在O(b)时间内运行。

def divide(a, b):
  '''Returns the decimal representation of the fraction a / b in three parts:
  integer part, non-recurring fractional part, and recurring part.'''
  assert b > 0
  integer = a // b
  remainder = a % b
  seen = {remainder: 0}  # Holds position where each remainder was first seen.
  digits = []
  while(True):  # Loop executed at most b times (as remainders must be distinct)
    remainder *= 10
    digits.append(remainder // b)
    remainder = remainder % b
    if remainder in seen:  # Digits have begun to recur.
      where = seen[remainder]
      return (integer, digits[:where], digits[where:])
    else:
      seen[remainder] = len(digits)

# Some examples.
for a, b in [(5,4), (1,6), (17,7), (22,11), (100,17)]:
  (i, f, r) = divide(a, b)
  print "%d/%d = %d.%s(%s)" % (a, b, i, ''.join(map(str, f)),''.join(map(str,r)))
# Output:
# 5/4 = 1.25(0)
# 1/6 = 0.1(6)
# 17/7 = 2.(428571)
# 22/11 = 2.(0)
# 100/17 = 5.(8823529411764705)

您还可以使用大小为b的数组(Python中的列表)而不是字典,这会稍快一些(不是渐近因素,而是常数因子)。

答案 1 :(得分:7)

你可以用长除法做到这一点。一次计算一个数字并减去得到一个余数,乘以10得到下一步的分子。当这个新分子与之前的一个分子匹配时,你知道你将从那一点开始重复。您只需要保留一堆先前的分子并在每次迭代时搜索它。

答案 2 :(得分:1)

我认为这就是你要找的......

public static String divide(int a,int b,boolean decimalDone,boolean isMultiplied,String result){
           if(a<b){
                a=a*10;

                if(!decimalDone ) {result+=".";decimalDone=true;}
                else if(isMultiplied) result+="0";
                isMultiplied=true;
                divide(a,b,decimalDone,isMultiplied,result);

           }
           else{
               result+=a/b;
               a=a%b;
               isMultiplied=false;
               divide(a,b,decimalDone,isMultiplied,result);
           }

           return result;
    }

答案 3 :(得分:0)

我不是专家,我认为这个解决方案效率可能不高,但至少很容易做到:

#you want to get a/b
from fractions import Fraction:
print float(Fraction(a,b))

评论被广泛接受