找到奇怪的int - Ruby嵌套循环错误

问题描述 投票:3回答:4

我在代码大战上做了这个问题:“给定一个数组,找到出现奇数次的int。总会有一个整数出现奇数次。”

码:

def find_it(seq)
  int = []
  for a in seq do
    count = 0
    for b in seq do
      if a == b
        count += 1
      end
    end
    if count % 2.0 != 0
      int << b
    end
  end      
  puts int.uniq[0].to_i
end

它针对一对输入进行了测试,但这两个数组的答案是错误的:

find_it([1,1,2,-2,5,2,4,4,-1,-2,5]) - 返回5而不是-1

find_it([1,1,1,1,1,1,10,1,1,1,1]) - 返回1而不是10

我的代码出了什么问题?

ruby nested-loops
4个回答
1
投票
if count % 2.0 != 0
      int << b
    end

你在这里遇到的问题是你推动b而不是整数数组,所以发生了什么,而不是你计算的值被推入,你推进b的最后一个值,这是最后一个值元素数组无论只要计数器是奇数的条件,尽管b和计数器彼此无关。所以要修复它你用一个替换b,以便它与第二个循环中的其他元素相比推送你正在测试的值

固定:

if count % 2.0 != 0
      int << a
    end

类似但更简单的代码执行类似的工作,除了更简短和更容易理解的方式是:

def find_it(seq)
  numberWithOddCount = 0
  seq.each do |currentElement|
    counter = 0
    seq.each { |elementToCompare| counter += 1 if currentElement == elementToCompare}
    numberWithOddCount = currentElement if counter % 2 != 0
  end
  numberWithOddCount
end

只需添加几个tid-bit,您也可以使用它们来缩短和简化代码。

快乐的编码!

注意:

您可以以创造性的方式利用内置的ruby方法,使代码在极少数行(甚至一行)中执行您想要的操作,例如@iGian在问题注释中所做的操作,但如果您仍然是ruby的新手,那么最好在学习它们时逐一使用这些方法,否则你会感到困惑。但是如果你愿意花时间学习它们,我建议你把他的代码和每个方法执行分成它自己的行,并输出每个方法所做的事情,以了解正在做什么。并分别练习使用。


1
投票

@aimen_alt对你的错误是正确的

但是让我们分解你的问题。

首先,您需要计算每个数字的外观。其次,你需要找到具有奇数计数的那个。因此,问题只有一个这样的数字,所以你可以立即归还。

您可以按照自己的方式在O(N^2)复杂性中通过扫描序列中每个项目的序列来进行(因此序列中的N项目乘以序列N = N*N的大小)。你可以通过构造一个Hash来线性地完成它,并且你将能够获得具有奇数值的键:

def find_it(seq)
  numbers = {}
  seq.each do |item|
    numbers[item] = numbers[item].to_i + 1
  end
  numbers.select{ |k,v| v.odd? }.first.first
end

为了更加惯用,您可以使用group_by对数字进行分组:

seq = [1, 2, 6, 1, 2]
seq.group_by{ |item| item }
#=> {1=>[1, 1], 2=>[2, 2], 6=>[6]}

你可以看到每个值都是一个数组,你只需要得到一个具有奇数项目的数据:

seq = [1, 2, 6, 1, 2]
seq.group_by{ |item| item }.select{ |k, v| v.size.odd? }
#=> {6=>[6]}

你要做的最后一件事是获得密钥的价值:

seq.group_by{ |item| item }.select{ |k, v| v.size.odd? }.keys.first

所以,最终的解决方案是

def find_it(seq)
  seq.group_by{ |item| item }
     .select{ |k, v| v.size.odd? }
     .keys
     .first
end

正如@pascalbetz所说:

def find_it(seq)
  seq.group_by{ |item| item }
     .find{ |k, v| v.size.odd? }
     .first
end

1
投票
def find_it(seq)
  seq.group_by{|x| x}.select{|k, v| (v.count % 2.0 !=0)}.first[0]
end

上面的代码将采用数组中的序列。在这里,我们按元素分组:

例如:

[1,1,2,-2,5,2,4,4,-1,-2,5].group_by{|x| x}
# => {1=>[1, 1], 2=>[2, 2], -2=>[-2, -2], 5=>[5, 5], 4=>[4, 4], -1=>[-1]}

在得到上述结果之后,我们发现其元素在选择条件下计数并不奇怪。

例如:

[1,1,2,-2,5,2,4,4,-1,-2,5].group_by{|x| x}.select{|k, v| (v.count % 2.0 !=0)}

我们将得到{-1=>[-1]}的结果

我们把关键作为结果元素。


0
投票

谢谢你们所有详细的答案,我现在就回答每个人的答案。我是Ruby的新手,我还在学习使用它们/ Big O表示法的方法/规则,所以我非常感谢大家的意见。 Codewar列出了一些排名靠前的解决方案这似乎是目前为止最快的:

def find_it(seq)   
   seq.detect { |n| seq.count(n).odd? } 
end
© www.soinside.com 2019 - 2024. All rights reserved.