2
votes

Sommes des nombres impairs dans le tableau

J'essaie d'obtenir la somme des nombres impairs dans un tableau. J'essaie d'écrire une méthode odd_sums qui accepte un tableau de nombres et renvoie la somme des nombres impairs.

def odd_sum(a.)
  new_arr = []
  i = 0
  while i < a.length
    if a.[i] % 2!=0
      new_arr << a.[i]
    end
    i += 1
  end
  return new_arr
end

J'ai les nombres impairs dans le tableau:

odd_sum([5,4,6,13,1]) # => 19
odd_sum([10,2,11,3]) # => 14
odd_sum([8,18]) # => 0 

Mais je ne peux pas obtenir la somme des nombres impairs. S'il vous plaît, aidez-moi.


1 commentaires

Votre fonction n'en ajoute aucun si les nombres. On dirait que c'est juste la construction d'un autre tableau. Pourquoi l'argument a. et pas seulement a ?


5 Réponses :


2
votes

écrivez ce code

a=[5,4,6,13,1]

puts a.select{|x|x.odd?}.sum


0 commentaires

0
votes

Vous pouvez utiliser .select avec .sum qui sont des méthodes de Classe énumérable et Classe Array

arr = Array.new(1_00000){rand(1..200)}

puts Benchmark.measure{arr.select(&:odd?).sum}
  0.000000   0.000000   0.000000 (  0.005207)

puts Benchmark.measure{arr.sum{|n|n.odd? ? n : 0}}
  0.000000   0.000000   0.000000 (  0.006952)

# mais puisque vous avez affaire à un tableau d'entiers, vous pouvez utiliser .odd ? qui fait la même chose que i% 2 == 0 comme indiqué par @Rajagopalan answer

def odd_sum(arr)
  arr.sum {|i| i.odd? ? i : 0}
end

Syntaxe alternative où vous pouvez passer un bloc à .sum Ici, nous soustrayons le nombre de somme s'il est pair. C'est un peu moins lisible mais c'est une syntaxe valide et c'est en fait la moins efficace pour votre cas d'utilisation. Voir les benchmarks.

def odd_sum(arr)
  arr.select{|i| i.odd? }.sum
  #or the shorthand version: arr.select(&:odd?).sum
end

Les benchmarks basés sur le commentaire de @max sur une autre réponse publiée.

def odd_sum(arr)
  arr.select{|i| i % 2 == 0}.sum
end


4 commentaires

@ElgunQuliyev voir la réponse mise à jour qui donne une référence pour la méthode la plus rapide


J'obtiens différents résultats de benchmarks pour un tableau avec des nombres aléatoires au lieu de 100000.times qui est séquentiel, ce qui peut affecter le résultat. a.sum {| i | j'ai même? ? i - i: i} est plus lent.


i-i ? Pourquoi pas juste 0?


@steenslag a mis à jour ma réponse et grâce à max benchmarks également mis à jour.



11
votes

Je suggère:

a = [5, 4, 6, 13, 1]

a.select(&:odd?).sum
#=> 19


1 commentaires

Selon mon benchmark , c'est en fait plus rapide que la somme avec un bloc. Allez comprendre.



6
votes

Il n'est pas nécessaire de faire plus d'un passage dans le tableau ou de créer un tableau temporaire.

def odd_sum(arr)
  arr.sum { |n| n.odd? ? n : 0 }
end

odd_sum([5,4,6,13,1]) #=> 19
odd_sum([10,2,11,3])  #=> 14
odd_sum([8,18])       #=>  0


4 commentaires

Fait intéressant, arr.select (&: odd?). Sum est plus rapide selon mon benchmark simple .


@max, je ne peux pas dire que je suis surpris, car sum est sans aucun doute très rapide. (Pour le plaisir, essayez arr.sum dans votre benchmark.) Il reste encore à créer un tableau temporaire, mais sans doute arr.select (&: odd?). Sum < / code> lit également mieux.


arr = Array.new (1000_0000) {rand (1 ... 20)} se bloque dans ma console ... pourquoi?


@lacostenycoder, je ne sais pas. Calculer 10 millions de nombres aléatoires et leur faire de la place ne semble pas être un gros problème.



3
votes

Correction de la syntaxe et utilisation d'un simple entier pour stocker la somme (vous n'avez pas besoin d'un tableau de stockage).

def odd_sum(a)
  sum = 0         
  i = 0
  while i < a.length
    if a[i] % 2 != 0
      sum += a[i]
    end
  i += 1
  end
  return sum      #return can be omitted
end

puts odd_sum([1, 2, 3, 4]) # 4

Regardez les autres réponses pour apprendre à utiliser plus de Ruby code similaire.


0 commentaires