zwei Brüche Addieren!!



  • Leute vielen Dank für die Antworten, @DocShoe es sind Keine Hausaufgaben sondern eine Aufgabe von einer alte Klausur, und glaube nicht das das ganze für 2 Punkten ist🤔 . und da ich keine Lösung dafür habe , wollte hier mal fragen, implementieren muss man hier keine Methode...
    @Jockelx Danke trotzdem , musst du aber nicht so werden, da du auf die Fragen hier im Forum nicht antworten musst, lass es, wenn der TE nicht so schreibt wie du gut findest😉



  • @wob sagte in zwei Brüche Addieren!!:

    und statt print wäre es sinnvoller, den operator<< zu implementieren.

    ich persönlich bevorzuge ein toString(). Da kann man dann nutzen wie man lustig ist und der Overhead ist meistens egal.



  • @Tyrdal sagte in zwei Brüche Addieren!!:

    ich persönlich bevorzuge ein toString(). Da kann man dann nutzen wie man lustig ist und der Overhead ist meistens egal.

    Dann heißt es bei der einen Klasse toString(), bei der nächsten to_string() und bei der dritten to_chars() und bei der vierten noch wieder anders. Wenn du generisch beliebige Objekte ausgeben willst, ist das doof. Aber du kannst einfach schreiben:

    std::ostream &operator<<(ostream &os, const DeinT o) { os << o.toString(); return os; }

    Ich würde den Operator immer klein halten - du kannst auch eine Fkt void print_to_stream(ostream&) in deiner Klasse implementieren und die im operator<< aufrufen - damit gehen auch virtuelle Funktionen für <<.



  • Ich hatte ja letzte Woche schon eine Musterlösung mit den exakt gleichen Methodendeklarationen geschrieben. Ich würde das so nicht schreiben, aber egal war nicht die Aufgabenstellung. Man kann die drei Methoden effektiv auf eine zurückführen, so dass der Code nur einmal wirklich vorhanden ist. Ich weiß jetzt nicht, ob das im Sinne des Aufgabensteller war, aber es bietet sich bei der so formulierten Aufgabe halt einfach an.

    #include <cmath>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <stdexcept>
    
    class Bruch {
    	int zaehler;
    	int nenner;
    public:
    	Bruch (const int z, const int n) : zaehler(z), nenner (n) {
    		if (0 == nenner) {
    			throw std::logic_error ("division by zero not defined");
    		}
    	};
    
    	Bruch add (Bruch op) {
    		return Bruch::add_2(*this, op);
    	};
    	static Bruch add_2 (Bruch op1, Bruch op2) {
    		int n = op1.nenner * op2.nenner;
    		int z = (op1.zaehler * op2.nenner) + (op2.zaehler * op1.nenner);
    		int m = sqrt (abs(std::min (n, z))) + 1;
    
    		for (int i = 2; i < m; ++i) {
    			while ((0 == z % i) && (0 == n % i)) {
    				z /= i;
    				n /= i;
    			}
    		}
    
    		Bruch r (z, n);
    		return r;
    	}
    	Bruch operator+ (Bruch op) {
    		return Bruch::add_2(*this, op);
    	};
    
    	void print() {
    		std::cout << zaehler << '/' << nenner << std::endl;
    	}
    };
    
    int main () {
    	try {
    		Bruch a (4, 5);
    		Bruch b (3, 10);
    		//Bruch x (1, 0);
    		a.print();
    		b.print();
    
    		Bruch c = a.add(b);
    		c.print();
    
    		Bruch d = Bruch::add_2 (a, b);
    		d.print();
    
    		Bruch e = a+b;
    		e.print();
    	}
    	catch (std::exception& e) {
    		std::cerr << "exception!!!" << "\n" << e.what() << std::endl;
    
    		return EXIT_FAILURE;
    	}
    
    	return EXIT_SUCCESS;
    }
    

    Nachtrag: Für die Wurzel aus dem Zähler den Betrag ergänzt.


  • Mod

    @john-0 sagte in zwei Brüche Addieren!!:

    Ich hatte ja letzte Woche schon eine Musterlösung mit den exakt gleichen Methodendeklarationen geschrieben. Ich würde das so nicht schreiben, aber egal war nicht die Aufgabenstellung. Man kann die drei Methoden effektiv auf eine zurückführen, so dass der Code nur einmal wirklich vorhanden ist. Ich weiß jetzt nicht, ob das im Sinne des Aufgabensteller war, aber es bietet sich bei der so formulierten Aufgabe halt einfach an.

    Der Sinn der Aufgabenstellung war überhaupt gar nicht, eine Implementierung der Funktionen vorzulegen. Es ging darum, Funktionssignaturen in einen passenden Aufruf zu überführen. Eine durchaus wichtige Grundfähigkeit bei der Nutzung von fremden Libraries. Also die Zeilen 46-59.

    Das sind dann auch (plus Leerzeilen und der Ausgabe von a, b) exakt die 5+3 Zeilen, zu denen ich weiter oben einen Tipp gegeben habe.



  • @wob sagte in zwei Brüche Addieren!!:

    @Tyrdal sagte in zwei Brüche Addieren!!:

    ich persönlich bevorzuge ein toString(). Da kann man dann nutzen wie man lustig ist und der Overhead ist meistens egal.

    Dann heißt es bei der einen Klasse toString(), bei der nächsten to_string() und bei der dritten to_chars() und bei der vierten noch wieder anders. Wenn du generisch beliebige Objekte ausgeben willst, ist das doof. Aber du kannst einfach schreiben:

    std::ostream &operator<<(ostream &os, const DeinT o) { os << o.toString(); return os; }

    Ich würde den Operator immer klein halten - du kannst auch eine Fkt void print_to_stream(ostream&) in deiner Klasse implementieren und die im operator<< aufrufen - damit gehen auch virtuelle Funktionen für <<.

    Tja nu, ich mag die streams in c++ halt so ganz und gar nicht. So hat jeder seine Vorlieben und Abneigungen.



  • @SeppJ sagte in zwei Brüche Addieren!!:

    Der Sinn der Aufgabenstellung war überhaupt gar nicht, eine Implementierung der Funktionen vorzulegen. Es ging darum, Funktionssignaturen in einen passenden Aufruf zu überführen. Eine durchaus wichtige Grundfähigkeit bei der Nutzung von fremden Libraries. Also die Zeilen 46-59.

    Letzte Woche fehlte der Hinweis auf eine Klasur ja noch. Wenn man das als Übungsaufgabe hat, erwarte ich halt, dass da ein lauffähiges Programm dabei heraus kommt, und man direkt sehen kann, ob die Lösung stimmt. Dazu kann man entweder direkt eine Implementation mitliefern, oder der Student hat das zu liefern.


Anmelden zum Antworten