Funktion schreiben



  • Hallöchen _,
    ich schreibe am Donnerstag eine Informatikklausur. Es handelt sich hier nur um die Grundlagen von C++. Ich bin gerade fleißig am Aufgaben lösen und es wäre nett wenn jemand mal auf meine Lösung schauen könnte 🙂

    A) Schreiben Sie eine Funktion, die ein eindimensionales double Feld und seine belegte Länge erhält. Gehen Sie davon aus, dass sie für die Werte im Feld eine vordefinierte Fkt aufrufen können deren Prototyp

    double get_value_(double x) lautet.

    Ihre Funktion soll das Feldelement bestimmen, dessen durch get_value berechneter Wert maximal ist und dieses und seinen Index zurückliefern.

    Lösung:

    (da die Funktion 2 Dinge zurückliefern soll, muss ich eine Struct definieren)

    struct erg{
    double maxw;
    int idx;
    }

    erg func( double p[]; const int LEN){

    double maxw = p[0]; // damit die Fkt weiß bei welchem Wert sie starten muss
    int idx = 0; // damit idx nicht irgendeinen sinnfernen Wert annimmt

    for( i= 0 ; i < LEN; i++){ // über die belegte Länge des arrays iterieren

    if( get_value(maxw) < get_value(p[i])){ // da ich maxw ja p[0] zugeordnet habe und i die Läufervariable ist

    maxw = p[i];
    idx = i;

    }

    }

    return erg;

    }

    Stimmt das so oder habe ich Mist fabriziert 😃



  • Grob überschlagen passt es. - Wenn du bereits in der ersten Zeile das 1. Element deinem Maxwert zuweist, kannst du in der Schleife direkt bei 1 anfagen statt bei 0. Du vergleichst den Wert sonst mit sich selbst.

    Das nächste mal bitte Code-Tags verwenden.



    1. Funktionsparameter trennt man durch , und nicht durch ;
    2. Du solltest eine Variable des Rückgabetyps anlegen und befüllen.

    Das übersetzt so nicht.



  • inflames2k schrieb:

    Grob überschlagen passt es. - Wenn du bereits in der ersten Zeile das 1. Element deinem Maxwert zuweist, kannst du in der Schleife direkt bei 1 anfagen statt bei 0. Du vergleichst den Wert sonst mit sich selbst.

    Das nächste mal bitte Code-Tags verwenden.

    alles klar das mit der 1 verstehe ich, aber was sind code tags ? 😕



  • DocShoe schrieb:

    1. Funktionsparameter trennt man durch , und nicht durch ;
    2. Du solltest eine Variable des Rückgabetyps anlegen und befüllen.

    Das übersetzt so nicht.

    wie meinst du das ? im Funktionsrumpf ?
    dann vielleicht sowas wie

    erg Ergebnis;

    aber wie übergebe ich dem dann maxw und idx ?



  • Naja, deine Funktion soll einen Wert vom Typ erg zurückgeben. Du gibst den Typen zurück, was so nicht funktionieren kann.

    Äquivalent dazu:

    int funktion()
    {
       return int; // das nix geht!
    }
    

    Verstehste?



  • Sowas in der Richtung ist gemeint:

    erg Ergebnis;
    Ergebnis.maxw = maxw;
    Ergebnis.idx = idx;
    
    return Ergebnis
    

    Ich würde dir empfehlen das zum Üben direkt am Computer zu machen. Da kannst du deinen Code direkt ausprobieren und siehst ob das Ergebnis richtig ist. (Ok, wenn man eine Funktion annehmen muss, die man noch simulieren müsste, wird das etwas aufwändiger, aber ist trotzdem besser zum üben).



  • Schlangenmensch schrieb:

    Sowas in der Richtung ist gemeint:

    erg Ergebnis;
    Ergebnis.maxw = maxw;
    Ergebnis.idx = idx;
    
    return Ergebnis
    

    Ergebnis ist in dem Sinne doch nur eine Variable vom Datentyp erg.

    Was passiert denn genau wenn ich Ergebnis.maxw = maxw schreibe ?

    ich meine ich will doch maxw dem maxw aus meiner struct zuweisen um es zurückliefern zu können.

    aber um auf die struct zuzugreifen müsste ich nicht:

    Ergebnis.erg maxw = maxw; ?

    oder muss ich das nicht weil ich Ergebnis schon dem Datentyp erg zugewiesen habe ?



  • Nein. Lies dir die Verwendung von struct in deinem Skript/Buch noch ein Mal durch.



  • wir haben leider weder noch ........ aber danke Leute für eure Hilfe hat mir auf jeden Fall geholfen 🙂



  • Hier mal etwas zu Structs: http://www2.informatik.uni-halle.de/lehre/c/c_struct.html

    Um es kurz zu halten:
    Mit einem Strukt definierst du dir einen eigenen Datentypen. In deinem Fall besteht der aus einem double und einem int.
    Wie bei jedem Variablentypen musst du dir eine Variable von dem Typen definieren, wenn du ihn benutzen möchtest.

    Du schreibst ja auch:

    int idx = 0;
    

    und nicht

    int = 0;
    


  • Die Aufgabe ist nicht ganz vollständig:
    Was soll bei einem leeren Eingabefeld passieren?

    Allgemein mag ich die Aufgabe nicht, denn ich finde, dass in reinem C++-Code Pointer+Länge nichts verloren haben, das riecht immer so nach C.

    Und ich frage mich gerade, wie man das mit der STL lösen würde. std::max_element wäre ja mal die erste Wahl, aber auch hier? Was ist, wenn das get_value langsam ist, wird das dann bei einem compare, wo ich das jeweils für beide Argumente aufrufen muss, nicht ineffizient? Und am Ende müsste ich das get_value nochmal aufrufen, um den Maximalwert zu ermitteln. Sehe ich das gerade richtig? Welchen Algorithmus würdet ihr hier nutzen?



  • Naiv, so wie OP das macht. Alle Ergebnisse erst in einen vector zu kopieren, um dann max_element zu benutzen würde ich nicht, das kostet nur Speicher und Laufzeit. Für große Count kann es sich lohnen, das nebenläufig über async zu machen, aber im ersten Ansatz eher nicht.

    std::pair<double,int> find_max( double* Values, std::size_t Count )
    {
       if( Count > 0 )
       {
          auto Result = std::make_pair( get_value( Values[0], 0 ) );
          for( std::size_t i = 1; i < Count; ++i )
          {
             auto tmp = get_value( Values[i] );
             if( tmp > Result.first ) Result = std::make_pair( tmp, i );
          }
          return Result;
       }
       return std::make_pair( 0, -1 );
    }
    


  • heyal schrieb:

    aber was sind code tags ? 😕

    Das sind code tags:

    struct erg
    {
    	double maxw;
    	int idx;
    }
    
    erg func( double p[]; const int LEN)
    {
    double maxw = p[0]; // damit die Fkt weiß bei welchem Wert sie starten muss
    int idx = 0; // damit idx nicht irgendeinen sinnfernen Wert annimmt
    
    	for( i= 0 ; i < LEN; i++) // über die belegte Länge des arrays iterieren
    	{
     		if( get_value(maxw) < get_value(p[i])) // da ich maxw ja p[0] zugeordnet habe und i die Läufervariable ist
     		{
    			maxw = p[i];
    			idx = i;
    		}
    	}
    return erg;
    }
    


  • Soweit ich weiß kann man Pointer auch als iteratoren verwenden. Dann könnte man das so lösen.

    std::pair<double,int> find_max( double* Values, std::size_t Count )
    {
       if( Count > 0 )
       {
          auto Result = std::max_value(Values, Values+Count) ;
          Return std::make_pair( *Result, std::distance(Values, Result);
       }
       return std::make_pair( 0, -1 );
    }
    

    Habe das jetzt nicht probiert, da ich im Moment nur via Smartphone hier bin, daher keine Gewähr



  • Das Problem dabei ist, dass Values nicht die zu betrachtenden Daten enthält, sondern das Argument für den get_value Aufruf. Was du bräuchtest ist ein max_element_if , wo du ein Prädikat mitgeben kannst.



  • DocShoe schrieb:

    Das Problem dabei ist, dass Values nicht die zu betrachtenden Daten enthält, sondern das Argument für den get_value Aufruf. Was du bräuchtest ist ein max_element_if , wo du ein Prädikat mitgeben kannst.

    Ich wusste doch, dass ich was übersehen habe.


Log in to reply