如何让Crystal编写的应用正确对二次多项式进行因式分解?
Crystal 内置了 Rational 分数类型,完全可以解决你当前的问题。
你现有代码的核心问题是用浮点数计算根,丢失了分数的分子分母信息,且存在浮点精度误差,无法还原为整系数因式。调整思路如下:
- 优先计算判别式
d = b² -4ac,先判断是否为负,负的话直接输出无实根;再判断开根号结果是否为整数,不是的话说明无法分解为整系数因式。 - 提取多项式三项的最大公因子
gcd_all,将a/b/c都除以该公因子后再进行后续计算,最终输出时把公因子放在最前面。 - 用分数形式存储根的分子分母,约分后直接转换为整系数因式:如果根为最简分数
p/q,对应的因式就是(qx - p),符号调整后即可得到符合要求的格式。
核心调整后的代码示例:
require "math" # 原有输入部分保持不变 puts "请输入ax² + bx + c形式的二次多项式参数:" puts "a: " a = gets exit if a.nil? a = a.to_i puts "b: " b = gets exit if b.nil? b = b.to_i puts "c: " c = gets exit if c.nil? c = c.to_i # 先判断判别式 d = b**2 - 4*a*c if d < 0 puts "无实根,解包含虚数。" exit end sqrt_d = Math.sqrt(d).to_i if sqrt_d ** 2 != d puts "无法分解为整系数二次因式" exit end # 提取全局公因子 gcd_all = a.gcd(b).gcd(c) a1 = a // gcd_all b1 = b // gcd_all c1 = c // gcd_all # 格式化因式的工具方法 def format_factor(den : Int32, const : Int32) x_part = den == 1 ? "x" : "#{den}x" if const == 0 return "(#{x_part})" end sign = const > 0 ? "+" : "-" abs_const = const.abs "(#{x_part} #{sign} #{abs_const})" end # 计算第一个根对应的因式 num1 = -b1 + sqrt_d den1 = 2 * a1 g1 = num1.gcd(den1) num1 //= g1 den1 //= g1 factor1 = format_factor(den1, -num1) # 计算第二个根对应的因式 num2 = -b1 - sqrt_d den2 = 2 * a1 g2 = num2.gcd(den2) num2 //= g2 den2 //= g2 factor2 = format_factor(den2, -num2) # 拼接输出结果 output = String.new output += gcd_all.to_s if gcd_all != 1 output += factor1 + factor2 puts output
测试你给出的 3x²+10x-8 用例,输出结果为 (3x - 2)(x + 4),符合预期。
你也可以直接使用 Crystal 的 Rational 类自动处理约分逻辑,只需要将根的计算改为 Rational 类型,直接调用 numerator 和 denominator 属性获取最简分数的分子分母即可,不需要手动算GCD约分。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

