检查数字是否在整数内(ruby)

ohh*_*hho 2 ruby

中国人不喜欢里面有数字4的数字.我将实施一个会员计划,会员编号不包括数字4,说:

number = 3
number.next.has4?
=> true
Run Code Online (Sandbox Code Playgroud)

如何has4?(有效地)完成该方法?

**编辑

感谢您的回答,我执行了简单的基准测试作为参考:

    class Fixnum
      def has4a?
        String(self).index('4') != nil
      end
    end

    class Fixnum
      def has4b?
        self.to_s[/4/]
      end
    end

    number = 3

    puts Time.now

    n = 0
    while n < 1000000
       number.next.has4a?
       n += 1
    end

    puts Time.now

    n = 0
    while n < 1000000
       number.next.has4b?
       n += 1
    end

    puts Time.now
Run Code Online (Sandbox Code Playgroud)

在我的电脑上显示的结果indexregex以下更快:

> ruby has4.rb
Tue May 11 18:36:04 +0800 2010
Tue May 11 18:36:05 +0800 2010
Tue May 11 18:36:11 +0800 2010
Run Code Online (Sandbox Code Playgroud)

以下编辑包含所有4种解决方案,并且可以轻松查看每种解决方案的持续时间:

class Fixnum
  def has4a?
    String(self).index('4') != nil
  end
end

class Fixnum
  def has4b?
    self.to_s[/4/]
  end
end

class Fixnum
  def has4c?
    temp = self
    while temp > 0
        if (temp % 10) == 4
            return true 
        end
        temp /= 10
    end
    false 
  end
end

class Fixnum
  def digits
    d, m = divmod(10)
    d > 0 ? d.digits + [m] : [m]
  end

  def has4d?
    self.digits.member?(4)
  end
end

before_A = Time.now

n = 0
has4 = 0
no4 = 0
while n < 5000000
   has4 += 1 if n.has4a? 
   no4  += 1 if !n.has4a?
   n    += 1
end

after_A = Time.now

puts after_A, has4, no4
puts "A duration: " + (after_A - before_A).to_s

before_B = Time.now

n = 0
has4 = 0
no4 = 0
while n < 5000000
   has4 += 1 if n.has4b? 
   no4  += 1 if !n.has4b?
   n    += 1
end

after_B = Time.now

puts after_B, has4, no4
puts "B duration: " + (after_B - before_B).to_s

before_C = Time.now

n = 0
has4 = 0
no4 = 0
while n < 5000000
   has4 += 1 if n.has4c? 
   no4  += 1 if !n.has4c?
   n    += 1
end

after_C = Time.now

puts after_C, has4, no4
puts "C duration: " + (after_C - before_C).to_s

before_D = Time.now

n = 0
has4 = 0
no4 = 0
while n < 5000000
   has4 += 1 if n.has4d? 
   no4  += 1 if !n.has4d?
   n    += 1
end

after_D = Time.now

puts after_D, has4, no4
puts "D duration: " + (after_D - before_D).to_s
Run Code Online (Sandbox Code Playgroud)

结果(关于Karmic的ruby 1.8.7(2009-06-12 patchlevel 174)[i486-linux]).随意从其他机器发布数据.

Tue May 11 16:25:38 -0400 2010
2874236
2125764
A duration: 35.375095
Tue May 11 16:26:19 -0400 2010
2874236
2125764
B duration: 40.659878
Tue May 11 16:27:38 -0400 2010
2874236
2125764
C duration: 79.12419
Tue May 11 16:31:28 -0400 2010
2874236
2125764
D duration: 229.573483
Run Code Online (Sandbox Code Playgroud)

对不起我以前的错字并感谢Matthew Flaschen修复它.这是我的基准:

    >ruby has4.rb
    Wed May 12 09:14:25 +0800 2010
    2874236
    2125764
    A duration: 18.186685
    Wed May 12 09:15:06 +0800 2010
    2874236
    2125764
    B duration: 40.388816
    Wed May 12 09:15:38 +0800 2010
    2874236
    2125764
    C duration: 32.639162
    Wed May 12 09:18:08 +0800 2010
    2874236
    2125764
    D duration: 150.024529

    >ruby -v
    ruby 1.8.7 (2010-01-10 patchlevel 249) [i386-mingw32]
Run Code Online (Sandbox Code Playgroud)

Mat*_*hen 7

class Fixnum
  def has4?
    String(self).index('4') != nil
  end
end
Run Code Online (Sandbox Code Playgroud)


R S*_*hko 6

如果要在不将数字转换为字符串的情况下以数学方式执行此操作,则以下算法将起作用:

while num > 0
    if (num % 10) == 4
        return true
    num = num / 10
return false 
Run Code Online (Sandbox Code Playgroud)

  • @Whelhelm,您可能会惊讶地发现字符串解决方案在大约一半的时间内执行.我在0到999,999之间测试了1,000,000个随机整数; 这需要6.6.跑几秒钟.字符串解决方案(`to_s [/ 4 /]`)取2.9. (3认同)