如何在不使用`uniq`方法的情况下在数组中查找重复项

时间:2015-05-31 01:11:40

标签: arrays ruby

我正在做一个挑战,要创建一个在数组中找到重复值的方法,并打印出一个没有重复项的新数组。 Ruby有一个内置的uniq方法;但是,我不被允许使用它。

在我看来,这应该有效:

def uniques(array) 
  tempPos = 0
  arrayPos = 0
  duplicate = true
  result = [] # array the result will be "pushed" too
  for arrayPos in 0..array.length
    for tempPos in 0..array.length
      # If the values at the indexes are the same. But the indexes are not the same.
      # we have a duplicate
      if array[arrayPos] == array[tempPos] && arrayPos != tempPos
        duplicate = true
      else
        duplicate = false
      end
      if duplicate == false
        result[arrayPos] = array[arrayPos]
      end
    end
    puts duplicate
  end
  puts result.inspect
end

输出:

uniq *this is the short hand user input to run the method*
false
false
false
false
false
false
[1, 2, 1, 4, 5, nil]

我一定是做错了。

5 个答案:

答案 0 :(得分:5)

您是否可以使用Set

require 'set'
array = [1, 2, 3, 3, 3, 4]

Set.new(array).to_a
#=> [1, 2, 3, 4]

另一种方法是迭代数组中的每一对:

array.each_cons(2).with_object([array.first]) do |pair, result| 
  result << pair.last unless pair.first == pair.last 
end
#=> [1, 2, 3, 4]

答案 1 :(得分:3)

有很多方法可以做到这一点。这是另一个。假设:

arr = [3,5,1,3,4,1,1]

构建体:

h = arr.group_by(&:itself)
  #=> {3=>[3, 3], 5=>[5], 1=>[1, 1, 1], 4=>[4]} 

重复项由:

给出
h.select { |_,v| v.size > 1 }.keys
  #=> [3, 1]

和没有重复的数组由:

给出
h.keys
  #=> [3, 5, 1, 4] 

答案 2 :(得分:2)

你的逻辑工作正常,如上所述,set会更好。您还可以对元素进行排序,然后找到具有相同值的相邻对,这些值与set不同,但运行时间比当前解决方案稍好一些:

要完善你现有的东西:

def uniques(array) 
  result = [] # array the result will be "pushed" too

  for arrayPos in 0...array.length
    duplicate = false
    for tempPos in 0...result.length
      # if the values at the indexes are the same... but the indexes are not the same...
      # we have a duplicate
      duplicate ||= (array[arrayPos] == result[tempPos])
    end
    if !duplicate
      result << array[arrayPos]
    end
  end

  puts result
end

稍微好一点的方法(仍然表现不佳):

def uniques(array) 
  result = [] # array the result will be "pushed" too

  for arrayPos in 0...array.length
    duplicate = result.include?(array[arrayPos])
    if !duplicate
      result << array[arrayPos]
    end
  end

  puts result
end

尽管此解决方案适用于学习作业,但您应注意其复杂性为O(n^2)(n平方)。这意味着对于大小为n的数组(例如n=10),您正在进行n平方(100)迭代。

它会成倍地恶化。如果您有一个长度为1,000,000的数组,那么您正在进行1,000,000,000,000次迭代。这就是为什么使用set如此重要,它的平均运行时间会低得多。

答案 3 :(得分:1)

这是一个相当简单的方法,可以利用array.include?

new = []
arr.each { |x| new << x unless new.include?(x)}
puts new

这会给你一个数组(new),它只包含原始数组中的唯一元素(arr)

答案 4 :(得分:0)

复制数组简单方法

arr1 = [1,3,4,5,6,6,6,1] 

arry = Array.new(arr1)

puts arry

使用OR运算符查找uniq数组的简便方法

arr1 = [1,3,4,5,6,6,6,1] 

arr2 = Array.new # creating new array

arry = arr1 | arr2 # compare two array using OR operator

puts arry