Java программа для выполнения арифметических операций c на дроби с использованием двух классов - PullRequest
0 голосов
/ 14 февраля 2020

Итак, я новичок в программировании, и у меня возникли проблемы с этим заданием для моего класса программирования. Назначение - создать программу Java, используя два класса, которые могут выполнять арифметику c для дробей. Я думаю, что моя главная проблема связана с объектно-ориентированными концепциями, которые мне нужно использовать для этого проекта, такими как классы и объекты. Я до сих пор не совсем понимаю, как работают конструкторы, методы доступа, мутаторы и др. c.

Первый класс, Fraction. java, содержит определения методов для всех операций арифметики c, а также методы, чтобы найти наибольший общий знаменатель, сократить дроби и распечатать результаты. Я создал методы printFraction, reduceFraction, gcd и addFraction, но мне еще предстоит попробовать вычитать, умножать или делить.

Второй класс, TestFraction. java, предназначен для реализации класса Fraction. и проверить его возможности. Я написал некоторый код в этом классе для тестирования класса Fraction, пока я все еще работаю, и методы, которые у меня есть (print, reduce и gcd), похоже, работают помимо addFraction. Похоже, он печатает адрес памяти или что-то вместо искомой дроби. У меня есть идея, почему, но я не уверен, как это исправить.

Вот мой код до сих пор. Как я уже сказал, я новичок, и я уверен, что это не очень хорошо, но я в основном беспокоюсь о том, чтобы закончить и заставить программу работать. Если у вас есть какие-либо советы, пожалуйста, постарайтесь, чтобы мне было легче их понять. Вот пример выходных данных: пример выходных данных

Дробь. 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 (очень неполный, состоит только из базовых c тесты сейчас):

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));
    }
}

Ответы [ 3 ]

2 голосов
/ 14 февраля 2020

Вот несколько предложений:

  • сделайте ваш класс неизменным (т.е. нет сеттеров / мутаторов и 2 переменные должны быть окончательными). На самом деле нет веских аргументов в пользу того, чтобы такой класс «value» мог измениться, и это сильно упростит ситуацию, потому что вам не нужно беспокоиться о том, что все изменится после создания объекта. Это также согласуется со всеми Number классами в API Java - ни один из них не позволяет изменять значение после построения.
  • обрабатывает нулевой знаменатель в конструкторе, вызывая исключение - тогда вам никогда не понадобится беспокоиться об этом случае где-либо еще
  • обрабатывать отрицательные дроби в конструкторе. Самый простой способ - всегда заканчивать конструктор положительным знаменателем. Таким образом, вы никогда не получите странно выглядящих дробных строк, таких как методы "3 / -4"
  • add Fraction.UNIT и Fraction.ZERO constants
  • add equalshashCode) - вы хотите, чтобы new Fraction(1, 1).equals(new Fraction(1, 1)) вернул true, и в настоящее время он вернул бы false
  • , также обрабатывая приведение к простейшей форме в конструкторе, если вы хотите, чтобы все дроби были сведены к простейшей форме.
  • если вы хотите обрабатывать дроби не в простейшей форме, тогда сделайте reduce методом в Fraction. Нет никаких оснований для этого, чтобы у публикуемого c stati c
  • был метод negate, который просто переключает знак числителя
  • , есть метод inverse, который просто переключает знаменатель и числитель
  • , тогда substract может быть просто композицией negate и add, а divide может быть композицией 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)); 

Это значительно упростит понимание неудачных тестов сообщений об ошибках.

В идеале у вас должно быть много таких тестов, показывающих, что ваш алгоритм работает во всех странных крайних случаях, которые он должен будет обработать.

1 голос
/ 14 февраля 2020

Добро пожаловать в StackOverflow.

Вы вызываете println для addFraction, который является методом, который возвращает объект типа Fraction. Когда вы вызываете println для объекта Java, он возвращает метод toString() объекта. По умолчанию этот метод «скрыт» и возвращает код ha sh объекта (странное число, которое вы видите).

Вот несколько вариантов, чтобы исправить это:

a ) Переопределите метод toString(). Просто добавьте следующий блок кода в класс Fraction:

@Override
public String toString() {
    return "numerator=" + numerator + ", denominator=" + denominator + "]";
}

b) Вместо этого выведите свойства объекта. Замените свою последнюю строку println следующим:

Fraction fraction = Fraction.addFraction(myFraction1, myFraction2);
System.out.println( String.format("numerator=%d, denominator=%d", fraction.getNumerator(), fraction.getDenominator()) );

Найдите время, чтобы gr asp концепции, объясненные @sprinter, так как это поможет вам написать лучший код в будущем. Удачи!

1 голос
/ 14 февраля 2020

Вы пытаетесь System.out.print объект. Чтобы это исправить, вы можете в классе дроби написать функцию toString () как здесь

и напечатать ваш результат как сейчас

public string toString(){
    return this.numerator+'/'+ this.denominator;

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...