2011-08-08 97 views
2

所以这段代码将计算其差值为K的数字对的总数。这是天真的方法,我需要优化它。建议?优化这个红宝石代码

test = $stdin.readlines 

input = test[0].split(" ") 

numbers = test[1].split(" ") 

N = input[0] 
K = input[1] 

count = 0 

for i in numbers 
    current = i.to_i 
    numbers.shift 
    for j in numbers 
     difference = (j.to_i - current).abs 
     if (difference == K) 
      count += 1 
     end 
    end 
end 

puts count 
+0

'N'有用吗?如果有另一部分代码我们看不到,你能否删除我们不需要的部分? XD – JMichelB

+0

对不起N是数字个数 – Evan

+0

'number.shift',是不是让循环保持不变?如果你有[1,2,3,4],不会'I'只取1和3作为值吗? – JMichelB

回答

4

本来对你给出一些输入和输出的例子不错,但我认为这是正确的。

require 'set' 

def count_diff(numbers, difference) 
    set = Set.new numbers 
    set.inject 0 do |count, num| 
    set.include?(num+difference) ? count+1 : count 
    end 
end 


difference = gets.split[1].to_i 
numbers  = gets.split.map { |num| num.to_i } 

puts count_diff(numbers, difference) 
0

我不知道红宝石所以我只是给你的大创意:

  1. 获取列表
  2. 保留布尔值如果在列表中的列表中存在
  3. 回路数阵列(称之为arr),标志着关闭数为真,看看是否arr[num-K]和/或arr[num+K]都是如此,num是在你的列表中的号码

它使用了相当多的内存,但这样的另一种方法是做到以下几点:

  1. 保持一个哈希表从一个整数n整数count
  2. 通过你的L到达ist,将num+Knum-K添加到哈希映射中,相应地增加count
  3. 查看您的列表并查看num是否在哈希映射中。如果是,通过count
1

有人增加您的柜台删除他的帖子,或者他的帖子被删除了...他有最好的解决办法,那就是:

test = $stdin.readlines 
input = test[0].split(" ") 
numbers = test[1].split(" ") 
K = input[1] 
count = 0 
numbers.combination(2){|couple| couple.inject(:-).abs == K ? count++} 
puts count 

,你甚至不需要N.

+0

这是比较慢,那么我的原因是为什么他删除它 – Evan

+1

如果我对丢失的数据是正确的(在问题的评论中提到),那么你至少运行两次太快。 – JMichelB