2016-05-10 108 views
0

一個數組由1,20組成。我正在嘗試確定數組中的最大重複次數和它的起始索引。查找數組中連續重複元素的索引和大小

實施例:

2 2 1 0 2 2 2 0 1 1 

應該接受的整數arguement,其可以是數字12

如果我們證明上述陣列上這些輸入中的一個的方法,所述輸出將是:

find_duplicates(2) 
=> 3,4 

find_duplicates(1) 
=> 2,8 

其中第一個數字表示重複的大小,第二個數字表示它的起始索引。

我試過循環數組,並與arr[i+1]arr[-1]比較,但這不是正確的方法。任何幫助將不勝感激。

編輯: 我沒有粘貼什麼,我在我問這個問題的時候已經嘗試過,這不是,如果我能感覺到我跟着這樣一些信心,我會做:

def find_status(arr,participant) 
    status = Array.new 
#arr is a two dimensional array 
for i in 0...arr.length do 
    current_line=arr[i] 
    cons=0 
    for j in 0...current_line.length do 
     #I worked on lots of if/else/case statements here, this is just one of them 
     if current_line[j] == participant 
      cons+=1 #count consecutive 
      if current_line[j]!=participant 
       cons=0 
      end 
     end 
     status[i] = cons 
    end 
end 
return status 
end 
+0

不清楚你的意思是「該方法應接受參數(1或2)並回復如下(輸入爲2):」。 – sawa

+0

感謝您的編輯。這意味着「該方法,應該接受兩個整數中的一個作爲輸入:」1「或」2「,並返回描述的輸出 – devwanderer

+0

Hello @TobySpeight對不起,這是我的錯。看起來我缺乏有用的ruby方法來解決問題的知識。(特別是'chunk') – devwanderer

回答

3
def max_run(arr, target) 
    _,b = arr.each_with_index. 
      chunk { |n,_| n==target }. 
      select { |tf,_| tf==true }. 
      max_by { |_,a| a.size } 
    b ? [b.size, b.first.last] : nil 
end 

arr = [1,1,2,2,2,3,1,1,1,1,2,2,2,2,3,3] 

max_run(arr,1) #=> [4, 6] 
max_run(arr,2) #=> [4, 10] 
max_run(arr,3) #=> [2, 14] 
max_run(arr,4) #=> nil 

target = 2,步驟如下:

enum0 = arr.each_with_index 
    #=> #<Enumerator: [1, 1, 2, 2, 2, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3] 
    # :each_with_index> 

我們可以看到,將這一enumera生成的元素TOR通過將其轉換爲一個數組:

enum0.to_a 
    #=> [[1, 0], [1, 1], [2, 2], [2, 3], [2, 4], [3, 5], [1, 6], [1, 7], [1, 8], 
    #  [1, 9], [2, 10], [2, 11], [2, 12], [2, 13], [3, 14], [3, 15]] 

繼續,

enum1 = enum0.chunk { |n,_| n==target } 
    #=> #<Enumerator: #<Enumerator::Generator:0x007f9beb9b0850>:each> 

這裏仔細檢查返回值。你可以把enum1想象成一個「複合枚舉器」。它會生成以下值:

enum1.to_a 
    #=> [[false, [[1, 0], [1, 1]]], [true, [[2, 2], [2, 3], [2, 4]]], 
    # [false, [[3, 5], [1, 6], [1, 7], [1, 8], [1, 9]]], 
    # [true, [[2, 10], [2, 11], [2, 12], [2, 13]]], [false, [[3, 14], [3, 15]]]] 

繼續,

c = enum1.select { |tf,_| tf==true } 
    #=> [[true, [[2, 2], [2, 3], [2, 4]]], 
    # [true, [[2, 10], [2, 11], [2, 12], [2, 13]]]] 
_,b = c.max_by { |_,a| a.size } 
    #=> [true, [[2, 10], [2, 11], [2, 12], [2, 13]]] 
b #=> [[2, 10], [2, 11], [2, 12], [2, 13]] 
b ? [b.size, b.first.last] : nil 
    #=> [[2, 10], [2, 11], [2, 12], [2, 13]] ? [4, [2,10].last] 
    #=> [4, 10] 
+0

非常感謝你提供詳細的,描述性很好的回覆@Cary,它包含了一些我以前從未使用過的部分,但是我會挖掘它。 – devwanderer

2
a = [2, 2, 1, 0, 2, 2, 2, 0, 1, 1] 

longest_sequence = 
a.each_index.select{|i| a[i] == 2}.chunk_while{|i, j| i.next == j}.max_by(&:length) 
# => [4, 5, 6] 

[longest_sequence.length, longest_sequence.first] # => [3, 4] 
+0

非常聰明的答案,合成數組由所需出現的索引組成。更容易理解。 – devwanderer

1

下面的解決方案可能是最有效的,因爲它是O(N)。它走過的陣列,收集塊:

arr.each.with_index.reduce({idx:-1, i: -1, len: 0}) do |memo, (e, i)| 
    memo[:i] = i if memo[:i] == -1 && e == 2  # at the beginning of chunk 
    memo[:len], memo[:idx] = [i - memo[:i], memo[:i]] \ 
    if memo[:i] >= 0 && i - memo[:i] > memo[:len] # save values if needed 
    memo[:i] = -1 unless e == 2      # reset index counter 
    memo 
end.reject { |k, _| k == :i }      # reject temporary index value 

#⇒ { 
# :idx => 4, 
# :len => 3 
# } 

要將其用作方法,接受的參數;只需在上面的代碼中用def find_duplicates number包裝上面的代碼並用數字代替2即可。是的,它返回散列而不是數組。

相關問題