in `>': Vergleich von Fixnum mit null ist fehlgeschlagen (ArgumentError) römische Ziffer Konverter in Ruby
Ich bin neu in Ruby und ich versuche ein Programm zu schreiben, welche die Umwandlung von römischen Ziffern zu zahlen.
Dies ist, was ich getan habe so weit:
roman_numbers = {"M" => 1000, "D" => 500, "C" => 100, "L" => 50, "X" => 10, "V" => 5, "I" => 1}
number_by_user = "MCMXCIX"
singlenum = number_by_user.split(//).reverse!
l = singlenum.length
result =0
result = roman_numbers[singlenum[0]]
puts result
for i in 0..l-1
if roman_numbers.key?(singlenum[i])
**if (roman_numbers[singlenum[i]] > roman_numbers[singlenum[i+1]])** #gives error
result = result - roman_numbers[singlenum[i+1]]
elsif (roman_numbers[singlenum[i]]== roman_numbers[singlenum[i+1]] || **roman_numbers[singlenum[i]] < roman_numbers[singlenum[i+1]])** #gives error
result = result + roman_numbers[singlenum[i+1]]
end
puts roman_numbers[singlenum[i]]
else
puts "One of the values are not roman"
break
end
end
puts "The number is: " , result
aber es gibt mir die folgende Fehlermeldung (siehe die Zeile mit Kommentar):
:in `>': comparison of Fixnum with nil failed (ArgumentError)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie eine off-by-one-Fehler. Arrays sind mit 0 indiziert. Ihre
singlenum.length
in diesem Fall ist 7, aber in deiner for-Schleife, Sie gehen bis um 6, dann versuchen Sie, die Referenzsinglenum[7]
zu vergleichen, umsinglenum[6]
.singlenum[7]
istnil
, damit es nicht verstehen < operator.Marc hat einen guten job, zu erklären, wo der Fehler war im code. Aber so ein Fehler sollte nie stattgefunden haben, in den ersten Platz, da in Ruby, alle Sammlungen, die bereits wissen, wie zu iterieren über sich selbst: Sie nicht zu tun, also können Sie auch nie machen so einen Fehler!
Hier ist ein Beispiel, wie eine Umsetzung könnte den gleichen Algorithmus in mehr idiomatische Ruby:
Sehen? Keine loops. Keine Indizes. Sie können nicht eine off-by-one-Fehler, auch wenn Sie versucht!
Bonus: eigentlich, das obige snippet hat enthalten ein Stück code zu verhindern, dass ein off-by-one-Fehler, allerdings bei einer viel höheren semantischen Ebene. Können Sie es finden?
{|x| numerals[x]}
ist klarer und mehr üblich.a.send(if n1 < n2 then :- else :+ end, n1)
🙂a + n1 * (n1 <=> n2)