我在代码战中曾问过这个问题:“给一个数组,找到出现奇数次的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
我的代码出了什么问题?
答案 0 :(得分:1)
if count % 2.0 != 0
int << b
end
这里的问题是将b而不是a推入整数数组,所以发生的是,推入b的最后一个值(即最后一个值)而不是推入计算的值尽管b和counter彼此无关,但只要计数器为奇数为条件,数组中的元素即可。为了解决这个问题,您可以将b替换为a,以便将您要测试的值与第二个循环中的其他元素进行比较
修复:
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位,您还可以利用它们来缩短和简化代码。
快乐编码!
注意:
您可以以创造性的方式利用内置的ruby方法,使代码在几行(甚至一行)中完成您想要的操作,例如@iGian在问题注释中所做的操作,但是如果您还是不熟悉ruby,那么最好在学习它们时一一使用这些方法,否则您会感到困惑。但是,如果您愿意花时间现在学习它们,我建议您带走他的代码,并将每个方法的执行分成自己的一行,并输出每个方法的操作以了解正在做什么。并练习分别使用。
答案 1 :(得分: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]}
我们将键作为结果元素。
答案 2 :(得分:1)
@aimen_alt正确对待您的错误
但让我们分解一下问题。
首先,您需要计算每个数字的出现。 其次,您需要找到带有奇数个外观的一个。 根据问题,只有一个这样的数字,因此您可以立即将其退回。
通过扫描序列中序列中的每个项目,您可以按照O(N^2)
的方式进行操作(因此,序列中的N
个项目乘以序列{{1}的大小) } = 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
您会看到每个值都是一个Array,而您只需要获得一个包含奇数项的值:
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
@pascalbetz提到:
def find_it(seq)
seq.group_by{ |item| item }
.select{ |k, v| v.size.odd? }
.keys
.first
end
答案 3 :(得分:1)
这个怎么样
def find_it(seq)
seq.reduce(:^)
end
^ -> 这个符号是按位XOR。 reduce 函数正在获取每个值并执行内部分配的任何工作。在这种情况下,它获取每个元素并执行 XOR 操作。第一个元素与零进行异或,下一个元素与前一个结果进行异或,依此类推。
就这样,我们找到了奇数元素。
异或运算的工作原理
0 ^ 2 = 2
4 ^ 4 = 0
如果您想了解更多关于异或的信息。请参阅this。
答案 4 :(得分:0)
感谢您提供所有详细的答案,现在我将讨论每个人的答案。我是Ruby的新手,我仍在学习方法/使用它们的规则/ Big O表示法,因此,我非常感谢大家的投入。 Codewar列出了一些排名最高的解决方案。这似乎是迄今为止最快的:
def find_it(seq)
seq.detect { |n| seq.count(n).odd? }
end