【问题标题】:Number Bases & Ruby - What is the fastest way to increment a variable intended for a specific number base?Number Bases & Ruby - 增加用于特定数字基数的变量的最快方法是什么?
【发布时间】:2013-04-11 01:17:09
【问题描述】:

我希望能够有一个变量“num”,我可以增加它并让它知道它的基数。

例如,如果 num 以 7 为底,等于 66,如果我做 num+= 1,则 num 应该设置为 100。

一个解决方案涉及 to_s 和 to_i,但是,有这么多的转换正在进行,它似乎不是很有效。

def increment_with_base(number, base)
  number_base_ten = number.to_s.to_i(base)
  number_base_ten += 1

  number_base_ten.to_s(base).to_i
end

还有比这更合适的吗?是否可以告诉 Ruby 我使用的是哪个数字基数,这样我就不必进行如此多的转换?

正如我在下面的评论中提到的,我非常熟悉数字基数 - 只是不是 Ruby 中的数字基数。我实际上需要显示每个递增的数字(我会增加很多)。

如果您知道问题的答案,则无需阅读下一部分。但是,我添加它是为了澄清我为什么要做我正在做的事情。除非您想了解更多信息,否则无需阅读以下内容。

有关更多信息,我正在生成一组图,其中每个节点只有 0 或 1 个转换。每个节点由一个数字表示,特定数字表示有向边指向的其他节点。例如,数字 4.3.1.0 是一个有四个节点的图,其中第一个节点到第四个节点有一条边,第二个到第三个节点有一条边,第三个到第一个节点有一条边,第四个节点没有有任何过渡。

因此,如果我想生成所有四个节点图,其中每个节点只有一个退出边,我需要从 0.0.0.0 计数到 4.4.4.4。

【问题讨论】:

  • 4.3.1.0 在技术上是一个字符串标识符,而不是一个数字。您是否正在寻找一种快速枚举所有此类字符串的方法,或者您是否还需要早期的数字表示用于其他目的?
  • 数字的基数没有区别。Ruby 有几种不同基数的数字的文字表达式,但它们在内部只是数字。毕竟,计算机上的一切都是二进制的。当基数的不同之处在于您在谈论数字的字符串表示时,而不是数字本身。因此,如果你要以任何方式处理base,你将处理字符串,并且像to_sto_i这样的方法是不可避免的。

标签: ruby numbers


【解决方案1】:

底数对算术无关紧要。数字只是数字,所有基数只是表示它们的方式略有不同。例如,667(xy 表示 x 以 y 为基数)是 4810,无论您在添加时考虑的基数如何一个,结果总是相同的数字: 1007 = 4910 = 3116 = ... 等等其他基础(即使是非常奇怪的基础,如黄金比例基础)。同样的操作,同样的结果。

只需对 数字 进行算术运算,并且只在真正重要时(例如,在为用户呈现时)担心基数。即使您需要在每次更新后显示它,您仍然可以节省几次转换,这不仅更快,而且更简单、更简洁。

【讨论】:

  • 我非常熟悉数字基数,只是不熟悉 Ruby 中的数字基数。您的建议实际上就是我正在做的,只是,我必须在指定的基数中将每个数字渲染到 n 为止。所以对于四进制,我实际上必须打印出 1 2 3 10 11 ... 一直到 n。所以这就是为什么我正在寻找一种“好”的增量方式。
  • 那又怎样?这样做更简单,并且可以节省多次转换。
  • 在任何情况下,Ruby 中的数字都是以 2 为基数的“本机”,除非您使用一些非标准的数字对象 - 即使以默认的以 10 为基数呈现 Ruby 整数实际上也是一种转换,只是一个对 Ruby 和大多数其他语言进行了很好的优化和默认行为。对于 OP 要求,您很可能只需要对字符串/显示进行非标准渲染,而不需要非标准的内部表示。
  • 德尔南,你不懂。您的解决方案是错误的,因为它与我在问题中发布的内容没有任何不同。我必须做的唯一算术是递增一,然后打印,然后递增一,然后再次打印,等等。所以我必须在每次递增后进行转换,因为我必须在每次递增后打印 - 而且正是我在我的问题中发布的。我不保存任何转换,因为必须输出每个数字。我没有做任何真正的算术 - 我只是加一。
【解决方案2】:

如果您只是想在不同的基数中枚举,则无需显式递增:

BASE = 4
MAX = 100
(0..MAX).each do |x|
   puts x.to_s( BASE )
end

这不是很多代码,而且速度非常快。符合要求吗?

为了更好地匹配您的潜在问题(以及我的理解?)

NODES = 4
BASE = NODES + 1
MAX = BASE ** NODES
(0...MAX).each do |x|
   puts ("0" * NODES + x.to_s( BASE )).chars.to_a[(-NODES..-1)].join('.')
end

我在笔记本电脑上将上述时间设置为 0.01 秒。但是如果您尝试使用 9 个节点,则需要更长的时间(不足为奇,您将循环 10 亿次!)

【讨论】:

  • 是的,只需要几个节点确实需要一段时间,这就是为什么我试图找到一种快速的方法来做到这一点!这至少是一个开始,并且比我所拥有的更好,谢谢:)
猜你喜欢
  • 2017-11-10
  • 1970-01-01
  • 2017-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多