Menu
CoddyTech

回顾:分数

本课属于 Coddy Ruby 学习旅程的“面向对象编程”单元。第 41 课,共 57 课。

challenge icon

挑战

困难

补全值类 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 在线编译器