Ruby—使用哈希算法求解Collatz序列

Ruby—使用哈希算法求解Collatz序列,ruby,algorithm,collatz,Ruby,Algorithm,Collatz,我对求解算法还很陌生,所以请容忍我 我已经解决了最大长度为1000000的Collatz序列,但我想通过使用哈希表查找已经存在的键来提高效率,从而使函数更快。然而,我知道我做错了什么,因为运行number=1000000只需要1-2秒,但运行起来仍然需要9-10秒。我对在算法中使用哈希表非常陌生,所以有人能告诉我我的方法中哪里做错了吗 非常感谢 def collatz(n) chain = 1 until n == 1 n = (n.even?) ? (n/2) : (n*3+1

我对求解算法还很陌生,所以请容忍我

我已经解决了最大长度为1000000的Collatz序列,但我想通过使用哈希表查找已经存在的键来提高效率,从而使函数更快。然而,我知道我做错了什么,因为运行number=1000000只需要1-2秒,但运行起来仍然需要9-10秒。我对在算法中使用哈希表非常陌生,所以有人能告诉我我的方法中哪里做错了吗

非常感谢

def collatz(n)
  chain = 1
  until n == 1
    n = (n.even?) ? (n/2) : (n*3+1)
    chain += 1
  end
  chain
end

def longest_chain2(number)
  cache = { 1 => 1 }
  start_num = 1
  longest = 1
  while start_num < number
    chain = cache[start_num]
    if chain > longest
      longest = chain
      longest_start = start_num
    end
    start_num += 1
    cache[start_num] = collatz(start_num)
  end
  return longest_start
end

puts longest_chain2(1000000)
def collatz(n)
链=1
直到n==1
n=(n.偶数?)?(n/2):(n*3+1)
链+=1
结束
链条
结束
def最长_链2(编号)
缓存={1=>1}
start_num=1
最长=1
当开始时_num<数字
链=缓存[开始数量]
如果链>最长
最长=链
最长开始时间=开始数量
结束
start_num+=1
cache[start\u num]=collatz(start\u num)
结束
返回最长时间(U)开始
结束
放置最长的\u链2(1000000)

在绞尽脑汁一整晚之后,我重新整理了整件事,把每一步都写了出来,意识到我的根本问题是我不能从以前调用collatz方法(因为该方法计算整个链,而我需要它停在我已经计算过的数字上)。下面是我的解决方案:

def longest_chain2(number)
  cache = { 1 => 1 }
  start_num = 1
  longest = 1
  while start_num < number
    n = start_num
    chain = 0
    while n != 1 && n >= start_num
      if n.even?
        n = n/2
      else
        n = 3*n+1
      end
      chain += 1
    end
    chain += cache[n]
    if chain > longest
      longest = chain
      longest_start = start_num
    end
    cache[start_num] = chain
    start_num += 1
  end
  return longest_start
end
def最长链2(编号)
缓存={1=>1}
start_num=1
最长=1
当开始时_num<数字
n=开始数量
链=0
而n!=1&&n>=开始数量
如果n.偶数?
n=n/2
其他的
n=3*n+1
结束
链+=1
结束
链+=缓存[n]
如果链>最长
最长=链
最长开始时间=开始数量
结束
缓存[开始数量]=链
start_num+=1
结束
返回最长时间(U)开始
结束

这样,我将添加不存在的键,同时调用cache[n]的值添加到链号中,直到该点。

此算法的实现方式正确吗?实际上,您并没有缓存任何内容,因为
start\u num
在每个循环上增加一个,并且您从来不会用
start\u num
以外的任何东西对哈希进行索引。因此,您将永远不会查找旧数据。也就是说,你的缓存永远不会被“命中”。事实上,查找似乎完全没有必要。我真的必须阅读缓存和散列,我认为我以前根本没有正确地实现它,而且它花费了和以前一样长的时间,因为我没有像你说的那样调用缓存。你的回答帮了我很大的忙,让我真正思考我要打哪把钥匙。谢谢哇,真的快多了。