有理数的表示方式
分数与有理数的互相转换
考虑分数13,其对应的有理数为0.(3),括号内的数会被无限追加到数值尾部,并且不存在0.(9),因为0.99…无限趋近于1。
我们先考虑如何将分数转换为有理数。我们先将整数部分放到有理数的最前面,接下来我们只需要考虑真分数ab,其中a<b。我们可以用小学学到的算术计算方式来不断做除法计算余数的方式得到有理数小数每一位。由于b是固定不变的,但是a在这个过程中可能会不断改变,即计算小数第i位前a的值为ai。假设j是最小的整数,存在某个更小的数i,满足ai=aj,那么这意味着之后所有数都会开始重复,而整个周期就是[i,j)。重复这个过程,直到找到第一次重复为止。
上面的过程,按照生日悖论,其长度的期望应该是O(√b),时间复杂度也应该如此。
接下来考虑如何从有理数转分数。我们先考虑形如0.(x)的小数,这里记k为x的位数,那么其对应的分数为x10k−1。因为x10k−1−0.(x)=x−x.(x)+0.(x)10k−1=0。
现在我们知道怎处理循环节了,下面考虑形如0.y(x)的小数,我们可以将其乘上10d,转换成y.(x)的形式,处理出分数后再除去10d即可。同理对于z.y(x)的数,先处理出0.y(x)对应的分数在加上整数z即可。
这里也给出了处理出分数的算法,这个算法很显然是O(n)的,n是小数的长度。
提供一道题目: SRM761 AddPeriodic。