长分区中余数的模式匹配

时间:2016-01-24 15:15:06

标签: c++ algorithm

我有一个工作算法来确定分数是否是无限重复以及哪些数字是重复的:

std::vector<integer_type> rd, dg;
integer_type d ( m_numer ), r;

do {

    integer_type q, aux;

    rd.push_back ( r = ( aux = _remquo<T, GCD, CHKOP> () ( d, m_denom, q ) ) < zero_ ?
                       integer_type ( -aux ) : aux );
    dg.push_back ( q < zero_ ? integer_type ( -q ) : q );

    d = op_multiplies() ( base, r );

} while ( ! ( r == zero_ || std::find ( rd.rbegin() + 1, rd.rend(), r ) != rd.rend() ) );

备注:

  • rd包含余数
  • dg包含小数结果数字
  • _remquo整数除以第一个和第二个操作数,并将余数存储在第三个参数中,忽略模板参数
  • base可被视为小数值10
  • m_numer是分数
  • 的分子
  • m_denom是分数的分母

问题:

我想至少摆脱std::find ( rd.rbegin() + 1, rd.rend(), r ) != rd.rend() ),也就是说我想要检测剩余部分是否已经出现过,并且充其量(为了摆脱rd向量)之间的距离从右到左的最后一位数到rd中的第一个重复数字。

问题是,我想在合理的时间内(不花费反向搜索剩余向量的时间)用 HUGE 重复数字序列(如1083448249/12172166)来分析数字。 / p>

有人有什么想法吗?

1 个答案:

答案 0 :(得分:2)

直接计算十进制扩展的数字,不带bignums。使用Floyd的循环检测方法来计算周期。在Python中(循环检测代码由Wikipedia提供):

#!/usr/bin/env python3
def floyd(f, x0):
    tortoise = f(x0)
    hare = f(f(x0))
    while tortoise != hare:
        tortoise = f(tortoise)
        hare = f(f(hare))
    mu = 0
    tortoise = x0
    while tortoise != hare:
        tortoise = f(tortoise)
        hare = f(hare)
        mu += 1
    lam = 1
    hare = f(tortoise)
    while tortoise != hare:
        hare = f(hare)
        lam += 1
    return (lam, mu)


def repeating_decimal(n, d):
    q, r = divmod(n, d)
    decimal = [str(q), '.']
    period, first_repeat = floyd(lambda r: 10 * r % d, r)
    for i in range(first_repeat + period):
        q, r = divmod(10 * r, d)
        decimal.append(str(q))
    return '{}({})'.format(''.join(decimal[:2 + first_repeat]), ''.join(decimal[2 + first_repeat:]))


print(repeating_decimal(1, 75))
print(repeating_decimal(1083448249, 12172166))