回顾:分数
本课属于 Coddy Ruby 学习旅程的“面向对象编程”单元。第 41 课,共 57 课。
挑战
困难补全值类 Frac。initialize(num, den) 会约分,并将符号保留在分子上;当 den 为 0 时,会引发 ZeroDivisionError,并显示 zero denominator。定义 +、-、* 和 /,让它们返回新的分数(除以零分数时,/ 会引发 ZeroDivisionError,并显示 division by zero);还要定义 -@、==、eql? 和 hash,使相等的分数成为同一个 Hash 键,并使用 Comparable 定义 <=>。to_s 返回 3/4,如果分母为 1,则返回 2。
提供的代码会读取这些命令:1/2 + 1/3(可以使用四种运算符中的任意一种)、neg 3/4、sort 1/2 1/3 3/4、max 1/2 2/3、uniq 1/2 2/4 1/3(打印数量和不重复的分数),以及 cmp 1/2 2/4(打印 =、< 或 >)。发生错误时会打印错误消息。
将代码写在 frac.rb 中。main.rb 包含提供的输入输出代码,不能修改。
亲手试试
require_relative 'frac'
# 提供的输入输出代码:保持原样。
input = []
while (line = gets)
input << line.chomp
end
def frac(text)
n, d = text.split("/").map(&:to_i)
Frac.new(n, d || 1)
end
input.each do |line|
parts = line.split
begin
case parts[0]
when "neg" then puts(-frac(parts[1]))
when "sort" then puts parts[1..].map { |t| frac(t) }.sort.join(" ")
when "max" then puts parts[1..].map { |t| frac(t) }.max
when "uniq"
distinct = parts[1..].map { |t| frac(t) }.uniq
puts "#{distinct.size}: #{distinct.join(" ")}"
when "cmp"
order = frac(parts[1]) <=> frac(parts[2])
puts ["<", "=", ">"][order + 1]
else
a = frac(parts[0])
b = frac(parts[2])
puts a.public_send(parts[1], b)
end
rescue ZeroDivisionError => e
puts e.message
end
end
面向对象编程中的所有课
自己练习: Ruby 在线编译器