gpt4 book ai didi

使用两个类对分数进行算术运算的 Java 程序

转载 作者:行者123 更新时间:2023-12-01 17:41:44 24 4
gpt4 key购买 nike

所以我是编程初学者,我在完成编程课的作业时遇到了麻烦。作业是使用两个可以对分数执行算术的类创建一个 Java 程序。我认为我的主要问题是我需要在这个项目中使用的面向对象的概念,例如类和对象。我仍然对构造函数、访问器、修改器等如何工作感到非常困惑。

第一个类 Fraction.java 包含所有算术运算的方法定义以及查找最大公约数、减少分数和打印结果的方法。我已经创建了 printFraction、reduceFraction、gcd 和 addFraction 方法,但我还没有尝试减法、乘法或除法。

第二个类 TestFraction.java 旨在实现 Fraction 类并测试其功能。我在这个类中编写了一些代码来测试 Fraction 类,同时我仍在工作,并且我拥有的方法(print、reduce 和 gcd)似乎除了 addFraction 方法之外也可以工作。看起来它打印了一个内存地址或其他东西,而不是我正在寻找的分数。我知道原因,但不知道如何解决。

这是到目前为止我的代码。就像我说的,我是一个初学者,我确信它不是很好,但我最担心的是完成并让程序运行。如果您有任何建议,请尽量让我容易理解。以下是示例输出:sample output

分数.java:

public class Fraction {
private int numerator;
private int denominator;

//no-arg constructor
Fraction() {
numerator = 0;
denominator = 1;
}

//constructor
Fraction(int numerator, int denominator) {
this.numerator = numerator;
this.denominator = denominator;
}

//accessor for numerator
int getNumerator() {
return numerator;
}

//mutator for numerator
void setNumerator(int num) {
numerator = num;
}

//accessor for denominator
int getDenominator() {
return denominator;
}

//mutator for denominator
void setDenominator(int denom) {
denominator = denom;
}

//printFraction method concatenates the numerator and denominator with a "/" string between them
static void printFraction(int numerator, int denominator) {
System.out.print(numerator + "/" + denominator);
}

//reduceFraction method uses the gcd method to print a reduced version of the fraction given
public static void reduceFraction(int numerator, int denominator) {
int smaller;
if (numerator < denominator) {
smaller = numerator;
}
else {
smaller = denominator;
}
for (int i = smaller; i > 0; --i) {
if (numerator % i == 0 && denominator % i == 0) {
System.out.print("Reduced form: " + (numerator/gcd(numerator, denominator)) + "/" + (denominator/gcd(numerator, denominator)));
break;
}
}
}

//recursive method that calls itself until it reduces completely to the gcd
public static int gcd(int numerator, int denominator) {
if (numerator % denominator == 0) {
return denominator;
}
return gcd(denominator, numerator % denominator);
}

public static Fraction addFraction(Fraction a, Fraction b) {
return new Fraction((a.numerator * b.denominator + a.denominator * b.numerator), (a.denominator * b.denominator));
}

TestFraction.java(非常不完整,目前仅包含基本测试):

import java.util.Scanner;
public class TestFraction {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);

System.out.print("Enter the first fraction's numerator and denominator separated by spaces: ");
Fraction myFraction1 = new Fraction(input.nextInt(), input.nextInt());
System.out.print("Enter the second fraction's numerator and denominator separated by spaces: ");
Fraction myFraction2 = new Fraction(input.nextInt(), input.nextInt());

Fraction.printFraction(myFraction1.getNumerator(), myFraction1.getDenominator());
System.out.println();
Fraction.printFraction(myFraction2.getNumerator(), myFraction2.getDenominator());
System.out.println();

System.out.print(Fraction.gcd(myFraction1.getNumerator(), myFraction1.getDenominator()));
System.out.println();
System.out.print(Fraction.gcd(myFraction2.getNumerator(), myFraction2.getDenominator()));
System.out.println();

Fraction.reduceFraction(myFraction1.getNumerator(), myFraction1.getDenominator());

System.out.println();
System.out.println(Fraction.addFraction(myFraction1, myFraction2));
}
}

最佳答案

以下是一些建议:

  • 使你的类不可变(即没有 setter /修改器,并且两个变量应该是最终的)。对于允许像这样的“值”类进行更改确实没有什么很好的论据,并且它将大大简化事情,因为您永远不需要担心在构造对象后事情会发生变化。它也与所有Number一致。 Java api 中的类 - 它们都不允许您在构造后更改值。
  • 通过抛出异常在构造函数中处理零分母 - 那么您永远不需要在其他地方担心这种情况
  • 在构造函数中处理负分数。最简单的方法是始终以分母为正数结束构造函数。这样你就永远不会得到像“3/-4”这样看起来很奇怪的分数字符串
  • 添加Fraction.UNITFraction.ZERO常量
  • 添加equals (和 hashCode )方法 - 你想要 new Fraction(1, 1).equals(new Fraction(1, 1))返回true目前它将返回 false
  • 如果您希望所有分数都简化为最简单形式,还可以在构造函数中处理简化为最简单形式。
  • 如果你想处理不是最简单形式的分数,那么 reduce Fraction 中的方法。没有理由将其设为公共(public)静态
  • negate仅切换分子符号的方法
  • inverse仅切换分母和分子的方法
  • 然后substract可以只是 negate 的组合和adddivide可以是 inverse 的组合和multiply
  • 使用toString转换为 String

最后的建议是学习使用 junit 和(IMO)assertj 并编写自定义断言以及在测试类中创建新分数的方法。然后你最终会得到更自然的测试用例,例如:

assertThat(fraction(2, 4)).isEqualTo(fraction(1, 2));
assertThat(fraction(1, 7).negate()).isEqualTo(fraction(-1, 7));
assertThat(fraction(4, 16)).hasNumerator(1).hasDenominator(4);
assertThatExceptionOfType(ArithmeticException.class)
.isThrownBy(() -> fraction(1, 0));

这将使失败的测试更容易理解错误消息。

理想情况下,您应该进行许多此类测试,以表明您的算法可以在需要处理的所有奇怪的边缘情况下正常工作。

关于使用两个类对分数进行算术运算的 Java 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60217009/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com