Arrays SockMerchant挑战Ruby数组#计数不计数?

Arrays SockMerchant挑战Ruby数组#计数不计数?,arrays,ruby,sorting,counting,Arrays,Ruby,Sorting,Counting,所以,我在HackerHand上做一个初学者挑战,ruby的一个奇怪行为让我难以置信 挑战是:找到并计算数组中有多少对。(袜子对) 这是我的密码 n = 100 ar = %w(50 49 38 49 78 36 25 96 10 67 78 58 98 8 53 1 4 7 29 6 59 93 74 3 67 47 12 85 84 40 81 85 89 70 33 66 6 9 13 67 75 42 24 73 49 28 25 5 86 53 10 44 45 35 47 11 81

所以,我在HackerHand上做一个初学者挑战,ruby的一个奇怪行为让我难以置信

挑战是:找到并计算数组中有多少对。(袜子对)

这是我的密码

n = 100
ar = %w(50 49 38 49 78 36 25 96 10 67 78 58 98 8 53 1 4 7 29 6 59 93 74 3 67 47 12 85 84 40 81 85 89 70 33 66 6 9 13 67 75 42 24 73 49 28 25 5 86 53 10 44 45 35 47 11 81 10 47 16 49 79 52 89 100 36 6 57 96 18 23 71 11 99 95 12 78 19 16 64 23 77 7 19 11 5 81 43 14 27 11 63 57 62 3 56 50 9 13 45)

def sockMerchant(n, ar)
counter = 0
ar.each do |item|
  if ar.count(item) >= 2
    counter += ar.count(item)/2
    ar.delete(item)
  end
end
counter
end

print sockMerchant(n, ar)
问题是,这不算什么。运行该函数后,在它的内部数组中,ar仍然有可数对,我再次运行它来证明这一点

还有更多。如果对数组进行排序,则其行为会有所不同

这对我来说没有意义

您可以检查此链接上的行为


在对集合进行迭代时,您正在从集合中删除项-预计会发生不好的事情。简而言之,如果您不想出现此类问题,请不要这样做,请参阅:

> arr = [1,2,1]
# => [1, 2, 1] 
> arr.each {|x| puts x; arr.delete(x) }
# 1
#  => [2]
我们在迭代中从未得到
2

一个简单的解决方案,即代码的一个小变体,可以如下所示:

def sock_merchant(ar)
  ar.uniq.sum do |item|
    ar.count(item) / 2
  end
end
这基本上就是找到所有独特的袜子,然后计算每双袜子的配对数

注意,它的复杂性是
n^2
对于数组中的每个唯一元素
n
,您必须遍历整个数组才能找到所有等于
n
的元素

另一种方法是,首先将所有袜子分组,然后检查每种袜子的数量:

ar.group_by(&:itself).sum { |k,v| v.size / 2 }
由于
ar.group_by(&:automother)
,缩写为
ar.group_by{x | x.automother}
将在数组中循环并创建如下所示的哈希:

{"50"=>["50", "50"], "49"=>["49", "49", "49", "49"], "38"=>["38"], ...}

通过对其调用
sum
,我们将对其进行迭代,对找到的元素数进行求和(
/2
)。

在对其进行迭代的同时,您正在从集合中删除项-预计会发生不好的事情。简而言之,如果您不想出现此类问题,请不要这样做,请参阅:

> arr = [1,2,1]
# => [1, 2, 1] 
> arr.each {|x| puts x; arr.delete(x) }
# 1
#  => [2]
我们在迭代中从未得到
2

一个简单的解决方案,即代码的一个小变体,可以如下所示:

def sock_merchant(ar)
  ar.uniq.sum do |item|
    ar.count(item) / 2
  end
end
这基本上就是找到所有独特的袜子,然后计算每双袜子的配对数

注意,它的复杂性是
n^2
对于数组中的每个唯一元素
n
,您必须遍历整个数组才能找到所有等于
n
的元素

另一种方法是,首先将所有袜子分组,然后检查每种袜子的数量:

ar.group_by(&:itself).sum { |k,v| v.size / 2 }
由于
ar.group_by(&:automother)
,缩写为
ar.group_by{x | x.automother}
将在数组中循环并创建如下所示的哈希:

{"50"=>["50", "50"], "49"=>["49", "49", "49", "49"], "38"=>["38"], ...}

通过对其调用
sum
,我们将对其进行迭代,将找到的元素数求和(
/2
)。

这些答案非常完美。你能详细说明一下单线解决方案吗?试着用再解释一下
组。\u。这些答案非常完美。你能详细说明一下单线解决方案吗?试着通过
再解释一下
组。\n什么是
n
?(在您的代码中没有使用它。)根据我的经验,
ar.size/2-ar.uniq.size
应该提供一个近似值,因为匹配袜子的数量似乎总是奇数。
Array.count
是直接在
Array
类上调用的方法,该类不存在
Array#count
正在讨论
Array
实例的实例方法。这似乎是学术性的,但这是一个巨大的差异。另一件需要考虑的是,红宝石大写字母在语法中有意义,并且保留或<代码> CANNAME/<代码>和<代码> COSTANTYNMENT/<代码>情况。此方法应称为
sock\u merchant
,以符合这些期望。什么是
n
?(在您的代码中没有使用它。)根据我的经验,
ar.size/2-ar.uniq.size
应该提供一个近似值,因为匹配袜子的数量似乎总是奇数。
Array.count
是直接在
Array
类上调用的方法,该类不存在
Array#count
正在讨论
Array
实例的实例方法。这似乎是学术性的,但这是一个巨大的差异。另一件需要考虑的是,红宝石大写字母在语法中有意义,并且保留或<代码> CANNAME/<代码>和<代码> COSTANTYNMENT/<代码>情况。此方法应被称为
sock\u merchant
,以符合这些期望。