给定一个数组,用下一个素数替换每个素数

时间:2017-09-27 22:46:08

标签: ruby

所以 #[11,13,17,23] => [13,17,19,29]

如果数字不是素数,那么函数只是返回数字 #[11,8,2,24] => [13,8,3,24]

我对最后一个数字(29)遇到了很多麻烦,出于某种原因,它会进入一个无限循环。我觉得有这么简单的解决方案,但它只是逃避了我..

def next_prime(arr)
  new_arr = []
  arr.each do |num|
    #puts num
    if prime?(num)
      p = false
      i = num + 2
      while !p
        p = prime?(i)
        i += 2
      end
      new_arr << i
    else
      new_arr << num
    end
  end
  new_arr
end

编辑:这是主要功能

def prime?(num)
  if num ==1
    return false
  elsif num < 3
    return true
  elsif num % 2 == 0 || num % 3 == 0
    return false
  end


  i = 5
  while i*i <= num
    if num % i == 0 || num % (i + 2) == 0
      return false
    end
    i += 6
  end
  return true
end

4 个答案:

答案 0 :(得分:2)

第一个数组对我来说效果不错,即使是29,除了事实上一切都比它应该高2,因为在检查你是否有一个可以修复的素数之后你加2对代码略有改动:

if prime?(num)
  p = false
  i = num
  while !p
    i += 2

    p = prime?(i)
  end
  new_arr << i

我遇到的唯一无限循环是当你在第二个数组中点击2时,因为要检查素数,你只需要继续增加2,所以你最终检查2的每个倍数,看它是不是主要。当然,你永远不会找到2的素数倍。要解决这个问题,在检查下一个素数之前不要递增2,如果增加1会起作用,你只需要检查两倍的数字:

if prime?(num)
  p = false
  i = num
  while !p
    i += 1

    p = prime?(i)
  end
  new_arr << i

您的最后一个问题是,prime?函数返回false为3,可以通过更改来修复:

elsif num <= 3
  return true

现在您的2个样品产量:

[11, 13, 17, 23] => [13, 17, 19, 29]
[11, 8, 2, 24] => [13, 8, 3, 24]

答案 1 :(得分:0)

我假设数组arr已排序。如果不是,则保存已排序值的原始索引,然后将其用于重新排序包含素数和非素数的值数组的元素。例如,如果

arr = [57, 13, 28, 6]

然后

indices = arr.each_with_index.sort.map(&:last)
  #=> [3, 1, 2 0]

主要方法的步骤如下:

  • 步骤1:创建一个由该方法返回的空数组a
  • 步骤2:创建一个枚举器enum,它生成一个无限的素数序列(2,3,5,7,...)。生成第一个素数m = enum.next #=> 2
  • 第3步:创建一个枚举器earr,生成给定数组arr的元素。
  • 第4步:考虑数组的下一个元素x = earr.next,它最初是数组的第一个元素。当没有更多的数组元素时,从循环中断并返回数组a
  • 步骤5:如果x不是素数,请将其保存到数组aa << x)并重复步骤4;否则转到第6步。
  • 第6步:{x是素数)如果x < m,将m保存到数组a并转到 第4步; else(即m <= x),获取下一个素数(m = enum.next)并重复此步骤。

require 'prime"

def next_primes(arr)
  enum = Prime.each
  m = enum.next    
  earr = arr.to_enum
  x = earr.next
  a = []
  loop do
    if x.prime?
      if x < m
        a << m
        x = earr.next 
      else
        m = enum.next
      end 
    else
      a << x
      x = earr.next
    end
  end
  a
end

next_primes([2, 6, 7, 23, 100])
  #=> [3, 6, 11, 29, 100]
next_primes([2, 6, 7, 7, 100])
  #=> [3, 6, 11, 11, 100]

答案 2 :(得分:0)

类似于@Cary Swoveland答案,但更惯用的Ruby恕我直言。

require 'prime'

def next_primes(ary)
  ary.map { |candidate| candidate.prime? ? next_prime(candidate) : candidate }
end

def next_prime(previous_prime)
  all_primes = Prime.each
  all_primes.find { |prime| prime > previous_prime }
end                            

next_primes([11,8,2,24]) # => [13, 8, 3, 24]
next_primes([11,13,17,23]) # => [13, 17, 19, 29]

答案 3 :(得分:0)

如果不是下一个质数,则查找下一个质数的解决方案:

def is_prime(num)
    if num<2
      return false
    end
    (2...num).each do |i|
      if num%i == 0
        return false
      end
    end
    return true

  end

def next_prime(arr)
    new_arr = []
    arr.each do |num|
        if is_prime(num)
            p = false
            i = num
            while !p
                i += 1
                p = is_prime(i)
            end
            new_arr<<i
        else
            new_arr<<num
        end
    end
    return new_arr

end
print next_prime([2,3,4,5])
puts

print next_prime([2, 6, 7, 23, 100]) #[3, 6, 11, 29, 100]