C++ 长除法中余数的模式匹配

C++ 长除法中余数的模式匹配,c++,algorithm,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_ ?

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

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() ) );
std::向量rd,dg;
整数类型d(m_numer),r;
做{
整数_类型q,aux;
r.push_back(r=(aux=_remquo()(d,m_denom,q))
注意事项:

  • rd
    包含剩余的数字
  • dg
    包含十进制结果数字
  • \u remquo
    integer将第一个和第二个操作数相除,并将余数存储在第三个参数中,忽略模板参数
  • base
    可被视为十进制值的
    10
  • m_numer
    是分数的分子
  • m_denom
    是分数的分母
问题:

我想至少去掉
std::find(rd.rbegin()+1,rd.rend(),r)!=rd.rend())
,也就是说,我想检测余数之前是否已经出现过,最好是(去掉
rd
向量)从右到左的最后一个数字到
rd
中第一个重复数字之间的距离

问题是,我想用一个巨大的重复数字序列来分析数字,就像在一个合理的时间内(一个不花费反向搜索余数向量的时间)


有人有什么想法吗?

直接计算十进制展开式的位数,而不使用bignums。使用弗洛伊德的周期检测方法计算周期。在Python中(循环检测代码由提供):


直接计算重复数字不是比实际进行长除法来检测重复数字更容易吗。@JSF欢迎您向我展示任何其他算法来实现这一点。我需要最终结果以及重复的数字和(如果有的话)直接在点后的非重复数字
13/30
=>0.4(3)@HeikoSchäfer该问题可简化为
1/N
情况。对于这种情况,请阅读以下内容:(可以推广到任何基础)。@奇怪的感谢,链接。我将讨论:)根据,如果可以通过素因子分解来解决。你也可以用代数的方法求出repetend的长度,这样你就知道什么时候找到了它。当然,它是否能在合理的时间内解决是另一个问题。天哪!好的,它是Python和另一个算法,但我想我会把它转换成C++,并给它一个尝试:)@ HiikoSo.For最舒服的语言,我把黑客在墙上。当你把lambda嵌入循环检波器时,有一个简化的机会。你让我的一天:我已经把它转换成C++并在代码ALL中集成它(甚至未优化),所有的测试用例都没有错误地运行!谢谢:-)
#!/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))