简体   繁体   English

SockMerchant挑战Ruby Array#count不计数?

[英]SockMerchant Challenge Ruby Array#count not counting?

So, i'm doing a beginners challenge on HackerHank and, a strange behavior of ruby is boggling my mind. 因此,我正在HackerHank上进行初学者挑战,而红宝石的一种奇怪行为令我感到困惑。

The challenge is: find and count how many pairs there are in the array. 挑战在于:找到并计算阵列中有多少对。 (sock pairs) (袜子对)

Here's my code. 这是我的代码。

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)

The problem is, it doesn't count well. 问题是,这算不上好。 after running the function, in it's internal array ar still have countable pairs, and i prove it by running it again. 运行该函数后,在其内部数组中ar仍具有可数对,我通过再次运行来证明这一点。

There's more. 还有更多。 If you sort the array, it behaves differently. 如果对数组排序,则其行为会有所不同。

it doesnt make sense to me. 这对我没有意义。

you can check the behavior on this link 您可以检查此链接上的行为

https://repl.it/repls/HuskyFrighteningNaturallanguage https://repl.it/repls/HuskyFrighteningNaturallanguage

You're deleting items from a collection while iterating over it - expect bad stuff to happen. 您正在迭代集合时从集合中删除项目-可能会发生不良情况。 In short, don't do that if you don't want to have such problems, see: 简而言之,如果您不想遇到此类问题,请不要这样做,请参阅:

> arr = [1,2,1]
# => [1, 2, 1] 
> arr.each {|x| puts x; arr.delete(x) }
# 1
#  => [2]

We never get the 2 in our iteration. 我们永远不会在迭代中得到2

A simple solution, that is a small variation of your code, could look as follows: 一个简单的解决方案(即您的代码的一个很小的变化)如下所示:

def sock_merchant(ar)
  ar.uniq.sum do |item|
    ar.count(item) / 2
  end
end

Which is basically finding all unique socks, and then counting pairs for each of them. 基本上是找到所有唯一的袜子,然后为每只袜子计数。

Note that its complexity is n^2 as for each unique element n of the array, you have to go through the whole array in order to find all elements that are equal to n . 注意,对于数组的每个唯一元素n ,其复杂度为n^2 ,您必须遍历整个数组才能找到等于n所有元素。

An alternative, first group all socks, then check how many pairs of each type we have: 另一种方法是,先将所有袜子分组,然后检查我们每种类型有几对:

ar.group_by(&:itself).sum { |k,v| v.size / 2 }

As ar.group_by(&:itself) , short for ar.group_by { |x| x.itself } 作为ar.group_by(&:itself)ar.group_by { |x| x.itself } ar.group_by { |x| x.itself } will loop through the array and create a hash looking like this: ar.group_by { |x| x.itself }将遍历数组并创建一个哈希,如下所示:

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

And by calling sum on it, we'll iterate over it, summing the number of found elements ( /2 ). 通过调用sum ,我们将对其进行迭代,将找到的元素sum/2 )相加。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM