0

我是 Ruby 的初学者。有人可以帮我为此编写代码吗?

给定一个数组,返回数组中只出现一次的元素。

例如,它应该通过以下测试用例:

  • 返回[1,4,5],给定[1,2,2,3,3,4,5]
  • 返回[1,3],给定[1,2,2,3,4,4]
4

3 回答 3

5

将项目放入数组中。 a = [1,2,2,3,4,4] 然后运行一些过滤器来获取您想要的项目。

a.group_by { |x| x }.reject { |k,v| v.count > 1 }.keys

#=> [1,3]

更新了 Stefan 的keys建议。

于 2013-07-24T16:15:13.507 回答
4
a = [1,2,2,3,3,4,5]
p a.select{|i| a.count(i) == 1}
# >> [1, 4, 5]


a = [1,2,2,3,4,4]
p a.select{|i| a.count(i) == 1}
# >> [1, 3]

基准

require 'benchmark'

a = [1,2,2,3,3,4,5]

n = 1000000
Benchmark.bm(15) do |x|
  x.report('priti') { n.times { a.select{|i| a.count(i) == 1} } }
  x.report('Jason') { n.times { a.group_by { |x| x }.reject { |k,v| v.count > 1 }.keys } }
  x.report('rogerdpack2') { n.times {
    bad = {}
    good = {}
    a.each{|v|
      if bad.key? v
        # do nothing
      else
        if good.key? v
          bad[v] = true
          good.delete(v)
        else
          good[v] = true;
        end
      end
    }
    good.keys            
  }
 }
end

有了这个结果

 priti             3.152000   0.000000   3.152000 (  3.247000)
 Jason             4.633000   0.000000   4.633000 (  4.845000)
 rogerdpack2       3.853000   0.000000   3.853000 (  3.886000)

并使用更大的数组:

需要“基准”

a = [1,2,2,3,3,4,5]*5 + [33,34]

n = 1000000
Benchmark.bm(15) do |x|
  x.report('priti') { n.times { a.select{|i| a.count(i) == 1} } }
  x.report('Jason') { n.times { a.group_by { |x| x }.reject { |k,v| v.count > 1 }.keys } }
  x.report('rogerdpack2') { n.times {
    bad = {}
    good = {}
    a.each{|v|
      if bad.key? v
        # do nothing
      else
        if good.key? v
          bad[v] = true
          good.delete(v)
        else
          good[v] = true;
        end
      end
    }
    good.keys            
  }
 }
 x.report('priti2') { n.times { a.uniq.select{|i| a.count(i) == 1} }}
end

你得到结果:

                  user     system      total        real
 priti            60.435000   0.000000  60.435000 ( 60.769151)
 Jason            10.827000   0.016000  10.843000 ( 10.978195)
 rogerdpack2       9.141000   0.000000   9.141000 (  9.213843)
 priti2           15.897000   0.000000  15.897000 ( 16.007201)
于 2013-07-24T16:11:16.133 回答
0

这是另一种选择:

a = [1,2,2,3,3,4,5]
b = {}
a.each{|v|
  b[v] ||= 0
  b[v] += 1
}
b.select{|k, v| v == 1}.keys

这是一个可能更快的(虽然更复杂),它被硬编码以查找“仅列出一次”的项目:

a = [1,2,2,3,3,4,5]
bad = {}
good = {}
a.each{|v|
  if bad.key? v
    # do nothing
  else
    if good.key? v
      bad[v] = true
      good.delete(v)
    else
      good[v] = true;
    end
  end
}
good.keys
于 2013-07-24T19:39:48.120 回答