Search code examples
javacomputer-sciencefractionsabstract-data-type

I'm trying to implement fractions as an ADT in Java, also arrays of fractions


I made 3 different packages with classes in them. One package is for simple fractions and another is for arrays of fractions. The smaller one is for implementing math functions mcm and MCD. The arrays of fractions main(fractioncollectionmain) doesn't print anything on screen when I run it. I'll leave ALL the code below. I hope someone can help!

util PACKAGE

MyMath class

package util;
/**
 * Libreria utile per calcolo di MCD e mcm
 * @author chiagger
 * @version Marzo 2021
 */

public class MyMath {
    
    /**
     * Calcola MCD tra due interi
     * @param a primo intero
     * @param b secondo intero
     * @return MCD tra i due interi
     */
    public static int mcd(int a, int b) {
            int resto;
            if (b > a){ // swap a,b
                int tmp = a;
                a = b;
                b = tmp;    
            }
            do {
                resto = a % b;
                a = b;
                b = resto;
            } while (resto != 0);
            return a;
    }
    
    /**
     * Calcola mcm tra due interi, sfruttando mcd
     * @param a primo intero
     * @param b secondo intero
     * @return mcm tra i due interi
     */
    public static int mcm(int a, int b) {
        return (a*b)/(MyMath.mcd(a, b));
    }
}

frazione PACKAGE

Frazione CLASS

package frazione;

import util.MyMath;
/**
 * Frazione come tipo di dato astratto (ADT)
 * @author chiagger
 * @version Marzo 2021
 */

public class Frazione {

    private int num, den;
    
    /**
     * Costruttore della funzione
     * @param n Numeratore
     * @param d Denominatore
     */
    public Frazione(int n, int d) {
        num = n;
        den = d;
        if (den == 0)
            throw new IllegalArgumentException("Impossibile dividere un numero per 0");
        else if ((n<0 && d<0) || (d < 0)) {
            num = -1*n;
            den = -1*d;
        }
    }
    
    /**
     * Costruttore della funzione
     * @param n Numeratore
     */
    public Frazione(int n) {
        num = n;
        den = 1;
    }

    /**
     * Recupera il numeratore
     * @return numeratore della frazione
     */
    public int getNum() {
        return num;
    }
    
    /**
     * Recupera il denominatore
     * @return Denominatore della frazione
     */
    public int getDen() {
        return den;
    }
    
    /** 
     * Controlla se una frazione è equivalente a quella attuale
     * @param f Frazione da confrontare con quella attuale
     * @return true se sono equivalenti, false se non lo sono
     */
    public boolean equals(Frazione f) {
        return f.getNum() * getDen() == f.getDen() * getNum();
    }
    
    /**
     * Calcola la funzione ridotta ai minimi termini.
     * @return Una nuova funzione equivalente all'attuale, ridotta ai minimi termini.
     */
    public Frazione minTerm() {
        if (getNum()==0) return new Frazione(getNum(), getDen());
        int mcd = MyMath.mcd(Math.abs(getNum()), getDen());
        int n = getNum() / mcd;
        int d = getDen() / mcd;
        return new Frazione(n, d);
    }

    /**
     * Calcola la somma con un'altra frazione
     * @param f Frazione da sommare all'attuale        
     * @return Nuova frazione risultato della somma
     */
    public Frazione sum(Frazione f) { //param f funzione da sommare all'attuale
        int n = this.num * f.den + this.den * f.num;
        int d = this.den * f.den;
        Frazione fSum = new Frazione(n, d);
        return fSum.minTerm();
    }
    
    /**
     * Calcola la somma con un'altra frazione (versione con mcm)
     * @param f Frazione da sommare all'attuale
     * @return Nuova frazione risultato della somma
     */
    public Frazione sumWithMcm(Frazione f) {
        int mcm = MyMath.mcm(f.getDen(), den);
        int n = ((mcm / den) * num) + ((mcm / f.getDen()) * f.getNum());
        int d = mcm;
        Frazione fSum = new Frazione(n, d);
        return fSum.minTerm();
    }
    
    /**
     * Calcola la sottrazione con un'altra frazione
     * @param f Frazione da sottrarre all'attuale
     * @return Nuova frazione risultato della sottrazione
     */
    public Frazione sub(Frazione f) { 
        int n = this.num * f.den - this.den * f.num;
        int d = this.den * f.den;
        Frazione fSub = new Frazione(n, d);
        return fSub.minTerm();
    }
    
    /**
     * Calcola la moltiplicazione con un'altra frazione
     * @param f Frazione da moltiplicare all'attuale
     * @return Nuova frazione risultato della moltiplicazione
     */
    public Frazione mul(Frazione f) { 
        int n = this.num * f.num;
        int d = this.den * f.den;
        Frazione fMul = new Frazione(n, d);
        return fMul.minTerm();
    }
    
    /**
     * Calcola la divisione con un'altra frazione
     * @param f Frazione da dividere all'attuale
     * @return Nuova frazione risultato della divisione
     */
    public Frazione div(Frazione f) { 
        int n = this.num * f.den;
        int d = this.den * f.num;
        Frazione fDiv = new Frazione(n, d);
        return fDiv.minTerm();
    }
    
    /** Calcola il reciproco della frazione
     * @return Nuova frazione che rappresenta il reciproco già ai minimi termini
     */
    public Frazione reciproco() { 
        Frazione fRec = new Frazione(getDen(), getNum());
        return fRec.minTerm();
    }
    
    /**
     * Recupera il numero reale equivalente alla frazione
     * @return Valore reale
     */
    public double getDouble() {
        return (double) getNum() / (double) getDen();
    }
    
    /**
     * Verifica se una frazione è maggiore o minore di quella passata
     * @param  f Frazione da confrontare
     * @return 0 se sono uguali, 1 se la Frazione è maggiore di quella passata, -1 se è minnore
     */
    public int compareTo(Frazione f) {
        double thisValue = this.getDouble();
        double otherValue = f.getDouble();
        if (thisValue == otherValue)
            return 0;
        else
            return thisValue > otherValue ? 1 : -1;
    }
    
      /**
         * Permette di passare un array di frazioni come parametro, e somma tutte le frazioni tra di loro
         * @param fs Array di frazioni
         * @return tutte le frazioni sommate tra loro
         */
      public static Frazione sumArray(Frazione[] tutte) {
            Frazione risultato = new Frazione(0);
            for (int i = 0; i < tutte.length; i++) {
                risultato = risultato.sum(tutte[i]);
            }
            return risultato.minTerm();
        }
      
      /**
         * Permette di passare un array di frazioni come parametro, e moltiplica tutte le frazioni tra di loro
         * @param fs Array di frazioni
         * @return tutte le frazioni moltiplicate tra loro
         */
        public static Frazione mulArray(Frazione[] tutte) {
            Frazione risultato = new Frazione(1);
            for (int i = 0; i < tutte.length; i++) {
                risultato = risultato.mul(tutte[i]);
            }
            return risultato.minTerm();
        }
        
        /**
         * Scrive la frazione sotto forma di stringa num/den
         * @return Frazione sotto forma di stringa num/den
         */
        public String toString() {
            String str = "";
            int num = getNum();
            int den = getDen();

            str += getDen() == 1 ? num : num + "/" + den;
            
            return str;
        }

}

MainFrazione CLASS

package frazione;

/**
 * Classe di test - main
 * @author chiagger
 * @version Marzo 2021
 */
public class MainFrazione {
    
    public static void main(String[] args) {
        
        //test costruzione frazione
        //test funzionamento metodi, accessor e toString
        System.out.println("--------------\n TEST COSTRUZIONE FRAZIONE"
                + "\n E TEST FUNZIONAMENTO METODI, ACCESSOR e getAsString");
        Frazione frazione1 = new Frazione(3, 12);
        System.out.println("Creata la frazione " + frazione1.toString());

        Frazione frazione2 = new Frazione(1, 4);
        System.out.println("Creata la frazione " + frazione2.toString());

        Frazione frazione3 = new Frazione(1, 8);
        System.out.println("Creata la frazione " + frazione3.toString());

        Frazione frazione4 = new Frazione(4, 1);
        System.out.println("Creata la frazione " + frazione4.toString());
        
        //test valori negativi
        System.out.println("--------------\n TEST VALORI NEGATIVI");
        Frazione frazione5 = new Frazione(-1, 8);
        assert(frazione5.getNum() == -1 && frazione5.getDen() == 8);
        System.out.println("Creata la frazione " + frazione5.toString());
        
        Frazione frazione6 = new Frazione(2, -3);
        System.out.println("Creata la frazione " + frazione6.toString());
        
        Frazione frazione7 = new Frazione(-5, -7);
        System.out.println("Creata la frazione " + frazione7.toString());

        //test funzionamento equals
        System.out.println("--------------\n TEST FUNZIONAMENTO EQUALS");
        if (frazione1.equals(frazione2)) // true
            System.out.println("Le frazioni " + frazione1.toString() + " e " + frazione2.toString() + " sono equivalenti");
        else
            System.out.println("Le frazioni " + frazione1.toString() + " e " + frazione2.toString() + " non sono equivalenti");

        
        if (frazione1.equals(frazione3)) // false
            System.out.println("Le frazioni " + frazione1.toString() + " e " + frazione3.toString() + " sono equivalenti");
        else
            System.out.println("Le frazioni " + frazione1.toString() + " e " + frazione3.toString() + " non sono equivalenti");
        
        
        if (frazione1.equals(frazione6)) // false
            System.out.println("Le frazioni " + frazione1.toString() + " e " + frazione6.toString() + " sono equivalenti");
        else
            System.out.println("Le frazioni " + frazione1.toString() + " e " + frazione6.toString() + " non sono equivalenti");

        //test funzionamento riduzione Minimi Termini
        System.out.println("--------------\n TEST RIDUZIONE AI MINIMI TERMINI");
        Frazione frazioneRid = frazione1.minTerm();
        
        System.out.println("La frazione " + frazione1.toString() + " ridotta ai minimi termini diventa " + frazioneRid.toString()); // 1/4
        
        frazioneRid = frazione6.minTerm();
        System.out.println("La frazione " + frazione6.toString() + " ridotta ai minimi termini diventa " + frazioneRid.toString()); // -2/3
        
        //test funzionamento somma fra due frazioni
        System.out.println("--------------\n TEST SOMMA NORMALE");
        Frazione sum = frazione6.sum(frazione7);
        System.out.println("-2/3 + 5/7 = " + sum.toString()); // 1/21
        
        //test funzionamento somma con mcm
        System.out.println("--------------\n TEST SOMMA CON mcm");
        Frazione sum2 = frazione2.sumWithMcm(frazione3);
        System.out.println("1/4 + 1/8 = " + sum2.toString()); //3/8
        
        sum2 = new Frazione(-1, 4).sumWithMcm(frazione3);
        System.out.println("-1/4 + 2/16 = " + sum2.toString()); //-1/8
        
        //test uguaglianza somma fra due frazioni con mcm e senza
        System.out.println("--------------\n TEST SOMMA CON mcm = SOMMA NORMALE");
        Frazione sumWithMcm = frazione6.sumWithMcm(frazione7);
        System.out.println("La somma ottenuta con mcm è " + sumWithMcm.toString()+ " senza è "+ sum.toString());
        
        //test funzionamento sottrazione fra due frazioni
        System.out.println("--------------\n TEST SOTTRAZIONE");
        Frazione sub = frazione2.sub(frazione3);
        System.out.println("1/4 - 1/8 =  " + sub.toString());
        
        //test funzionamento prodotto fra due frazioni
        System.out.println("--------------\n TEST PRODOTTO");
        Frazione mul = frazione4.mul(frazione5);
        System.out.println("4 * -1/8 = " + mul.toString()); // -1/2
        
        //test funzionamento divisione fra due frazioni
        System.out.println("--------------\n TEST DIVISIONE");
        Frazione div = frazione6.div(frazione2);
        System.out.println("-2/3 : 1/4 = " + div.toString()); // -8/3
        
        //test funzionamento compareTo
        System.out.println("--------------\n TEST compareTo");
        System.out.println("il confronto tra 3/12 e 1/4 è "+ frazione1.compareTo(frazione2)); //uguale
        System.out.println("il confronto tra -1/8 e 1/8 è "+ frazione5.compareTo(frazione3)); //-1 fraz5<fraz3
        System.out.println("il confronto tra 1/8 e -1/8 è "+ frazione3.compareTo(frazione5)); //1 fraz3>fraz5
        
       //test funzionamento getDouble
        System.out.println("--------------\n TEST getDouble");
        System.out.println("valore reale associato a " + frazione5.toString() + " è "+ frazione5.toString());
    }
}

*fractionCollection PACKAGE

FractionCollection CLASS

package fractionCollection;

import java.util.StringJoiner;

import frazione.Frazione;

public class FractionCollection {
    private Frazione[] innerContainer;
      private final int DEFAULT_PHYSICAL_SIZE = 10;
      public int size;
      private int physicalSize;
     
      /**
       * Costruisce una collezione (logicamente vuota) 
       * @param physicalSize dimensione fisica iniziale dell'array parametro
       */
    public FractionCollection(int physicalSize) {
        this.size = 0;
        this.physicalSize = physicalSize;
        this.innerContainer = new Frazione[physicalSize];
    }
    
    /**
     * Costruisce una collezione (logicamente vuota) con dimensione fisica iniziale 
     * di default (10)
     */
    public FractionCollection() {
        this.size = 0;
        this.physicalSize = DEFAULT_PHYSICAL_SIZE;
        this.innerContainer = new Frazione[DEFAULT_PHYSICAL_SIZE];
    } 
    
    /**
     * Costruisce una collezione dato un array di frazioni (parametro) che sarà 
     * copiato in quello interno
     * @param frz array di frazioni
     */
    public FractionCollection(Frazione[] frz) {
        this.physicalSize = frz.length;
        this.innerContainer = new Frazione[this.physicalSize];
        for (int i = 0; i < this.physicalSize; i++) {
            this.innerContainer[i] = frz[i];
        }
    }
    
    /**
     * Restituisce la dimensione logica dell'array di frazioni
     * @return
     */
    public int size() {
        int size = 0;
        while (size < this.physicalSize) {
            if(this.innerContainer[size] != null) 
                size++;
        }
        return size;
    }
    
    
    /**
     * Restituisce l'elemento i-esimo (parametro) della collezione
     * @param index Indice che si vuole restituire
     * @return elemento in quell'indice
     */
    public Frazione get(int index) {
        if (index < this.physicalSize)
            return this.innerContainer[index];
        else
            throw new IndexOutOfBoundsException();
    }
    
    /**
     * Aggiunge un elemento ALLA FINE della collezione e incrementa la dimensione 
     * logica; se non c'è posto: 
     * (1) crea un nuovo array grande il doppio del corrente, 
     * (2) vi copia tutte le frazioni del corrente 
     * (3) rende corrente il nuovo array
     * (4) Inserisce l'elemento nella prima posizione disponibile del nuovo array doppio.
     * @param frz
     */
    public void put(Frazione frz) {
        int logicSize = this.size;
        if (logicSize <= this.physicalSize) {
             /*for(int i=0; i< this.physicalSize; i++) {
                if(this.innerContainer[i] != null)
                    continue;
                else if (this.innerContainer[i] == null) {
                    this.innerContainer[i] = frz;
                    break; */ //qua tengo conto anche dei null in mezzo
                this.innerContainer[logicSize++] = frz;
                }
        else {
            Frazione[] doubleInnerContainer = new Frazione[2*this.physicalSize];
            for (int i = 0; i < this.size; i++) {
                doubleInnerContainer[i] = this.innerContainer[i];
            }
            /*for(int i=0; i< (2*this.physicalSize); i++) {
                if(doubleInnerContainer[i] != null)
                    continue;
                else if (doubleInnerContainer[i] == null) {
                    doubleInnerContainer[i] = frz;
                    break;
                }
            }
            this.innerContainer = doubleInnerContainer; */
            doubleInnerContainer[logicSize++] = frz;
            this.innerContainer = doubleInnerContainer;
        }
    }
    
    /**
     * Elimina un elemento dalla posizione i-esima (parametro) della collezione e, se 
     * necessario, compatta la collezione eliminando il "buco" usando un nuovo array
     * @param index indice dell'elemento da eliminare
     */
    public void remove(int index) {
         if (index <= this.physicalSize) {
              this.innerContainer[index] = null;
             Frazione[] newContainer = new Frazione[index-1];
             for (int i= 0, j=0; i < this.physicalSize; i++) {
                 if (i != index) 
                    newContainer[j++] = this.innerContainer[i];
             }
          } 
          else
            throw new IndexOutOfBoundsException();
    }
    
    /**
     * Scrive l'array di funzioni sotto forma di stringa [f1, f2, f3]
     */
    public String toString() {
        StringJoiner sj = new StringJoiner(", ", "[", "]");
        for (int i = 0; i < this.physicalSize; i++) {
            sj.add(this.innerContainer[i].toString());
        }
        return sj.toString();
      }
    
    /**
     * Permette di sommare i due array indice per indice, solo se
     * gli array hanno la stessa dimensione logica
     * @param collezioneB secondo array di frazioni
     * @return array di frazioni sommate
     */
    public FractionCollection sumArrays(FractionCollection frz) {
        if (this.size() != frz.size() || this.size() == 0) {
          return null;
        }

        FractionCollection result = new FractionCollection(this.size());
        for (int i = 0; i < this.size(); i++) {
          result.put(get(i).sum(frz.get(i)));
        }
        return result;
      }
    
    /**
     * Permette di sottrarre i due array indice per indice, solo se
     * gli array hanno la stessa dimensione logica
     * @param otherSet secondo array di frazioni
     * @return array di frazioni sottratte
     */
    public FractionCollection subArrays(FractionCollection frz) {
        if (this.size() != frz.size() || this.size() == 0) {
          return null;
        }

        FractionCollection result = new FractionCollection(this.size());
        for (int i = 0; i < this.size(); i++) {
          result.put(get(i).sub(frz.get(i)));
        }
        return result;
      }
    /**
     * Permette di moltiplicare i due array indice per indice, solo se
     * gli array hanno la stessa dimensione logica
     * @param otherSet secondo array di frazioni
     * @return array di frazioni moltiplicate
     */
    public FractionCollection mulArrays(FractionCollection frz) {
        if (this.size() != frz.size() || this.size() == 0) {
          return null;
        }

        FractionCollection result = new FractionCollection(this.size());
        for (int i = 0; i < this.size(); i++) {
          result.put(get(i).mul(frz.get(i)));
        }
        return result;
      }
    
    /**
     * Permette di dividere i due array indice per indice, solo se
     * gli array hanno la stessa dimensione logica
     * @param otherSet secondo array di frazioni
     * @return array di frazioni moltiplicate
     */
    public FractionCollection divArrays(FractionCollection frz) {
        if (this.size() != frz.size() || this.size() == 0) {
          return null;
        }

        FractionCollection result = new FractionCollection(this.size());
        for (int i = 0; i < this.size(); i++) {
          result.put(get(i).div(frz.get(i)));
        }
        return result;
      }
    
} 

FractionCollectionMain CLASS

package fractionCollection;
import frazione.Frazione;

public class CollectionMain {
    

  public static void main(String[] args) {
    
      FractionCollection collezioneA = new FractionCollection(4);
      collezioneA.put(new Frazione(1,3));
      collezioneA.put(new Frazione(2,3));
      collezioneA.put(new Frazione(-1,2));
      collezioneA.put(new Frazione(1,6));
      
      FractionCollection collezioneB = new FractionCollection(4);
      collezioneB.put(new Frazione(1,5));
      collezioneB.put(new Frazione(2,8));
      collezioneB.put(new Frazione(1,7));
      collezioneB.put(new Frazione(-1,6));
      
      FractionCollection somma = collezioneA.sumArrays(collezioneB);
      System.out.println(somma.toString());
      
      FractionCollection prodotto = collezioneA.mulArrays(collezioneB);
      System.out.println(prodotto.toString());
      System.exit(1);
  }
 
  
}

Why doesn't this main print anything??

I'm sorry I had to paste all of this code but I'm just a beginner at Java and i honestly don't know what is going on... I hope someone can help. Thank you so much!


Solution

  • You have an error in your FractionCollection.put method. When you add a fraction to the innerContainer array you increment logicSize, but it's just a local variable. The actual this.size remains unchanged. Instead of

    this.innerContainer[logicSize++] = frz;
    

    you need

    this.innerContainer[size++] = frz;
    

    Also, in the FractionCollection.toString method you need to iterate only over the actual elements of the collection, so

    for (int i = 0; i < this.physicalSize; i++) {
    

    should be replaced with

    for (int i = 0; i < this.size; i++) {