C++ std Funktion für Intervalle



  • Hallo!

    Gibt es in der STL bereits eine Funktion ob sich eine Zahl in einem Intervall befindet?

    Zum Beispiel die Zahl 5 im Intervall 1 bis 10 befindet?



  • Brauchst du für alles, was mit einer einzeiligen if-Anweisung zu erledigen ist, eine STL-Funktion? 😕



  • Sieht sauberer aus:

    if(im_intervall(1,10,5))
    

    als

    if(5<=10 && 5>=10)
    

    vor allem bei längeren ausdrücken und [a,b),(a,b),[a,b] ... etc. man muss ja nicht 1000 mal das Rad neu erfinden.



  • Es spricht jedenfalls nichts dagegen sich eine solche Hilfsfunktion zu schreiben.

    bool InInterval(int a, int b, int c) { return a <= c && b >= c; }
    


  • --- schrieb:

    Es spricht jedenfalls nichts dagegen sich eine solche Hilfsfunktion zu schreiben.

    bool InInterval(int a, int b, int c) { return a <= c && b >= c; }
    

    Habe ich bereits. Würde aber gerne alles, was schon in der STL implementiert ist, nutzen bevor ich unnötig code dazuschmeisse



  • gibts nicht.

    ich würd allerdings keine einfache fkt schreiben sondern so was hier in der richtung:

    template<typename T>
    struct intervall
    {
      intervall(T min, T max) : min(min), max(max) {}
    
      bool ist_enthalten(T c) const
      {
        assert(min <= max && "grenzen falsch");
        return c >= a && c <= b;
      }
    
      T min;
      T max;
    };
    
    int main()
    {
      intervall<int>(0, 10).ist_enthalten(5);
    }
    

    da kann man sicherlich noch ne ganze menge sinnvolles zeugs einbauen...^^

    bb



  • if( logical_and<bool>()(
            greater<int>()(i,1), less<int>()(i,10)))
        {
            cout << "bingo";
        }
    

    Spaß beiseite...
    Jeder, der dein Code liest wird ein

    if(i<=10 && i>=1)
    

    schneller und besser verstehen als

    if(im_intervall(1,10,i))
    

    Es schreibt ja auch kein Mensch if (less<int>... .
    Das wird nur in Verbindung mit Algorithmen und Containern oder anderen generischen Kunststückchen gebraucht.



  • unskilled schrieb:

    template<typename T>
    struct intervall
    {
      intervall(T min, T max) : min(min), max(max) {}
    
      bool ist_enthalten(T c) const
      {
        assert(min <= max && "grenzen falsch");
        return c >= a && c <= b;
      }
    
      T min;
      T max;
    };
    

    Die C++0x Lösung. Warum einfach wenns auch umständlich geht^^



  • brotbernd schrieb:

    Jeder, der dein Code liest wird ein

    if(i<=10 && i>=1)
    

    schneller und besser verstehen als

    if(im_intervall(1,10,i))
    

    Du gehst wie selbstverständlich davon aus, dass da immer ein i vorkommt. Aber wenn i ein Ausdruck ist, der nicht mehrfach ausgewertet werden soll, ist die zweite Variante eindeutig vorzuziehen. Sonst musst du erst wieder eine Zwischenvariable einführen und alles wird wieder komplizierter.

    Es schreibt ja auch kein Mensch if (less<int>... .
    Das wird nur in Verbindung mit Algorithmen und Containern oder anderen generischen Kunststückchen gebraucht.

    Vielleicht hat der OP ja genau das vor.



  • brotbernd schrieb:

    if(i<=10 && i>=1)
    

    Sowas verstehe ich nicht. Ein
    if(1<=i && i<=10)
    ist soviel schöner.

    Die intervall Funktionmacht aber durchaus Sinn.



  • player4245 schrieb:

    unskilled schrieb:

    template<typename T>
    struct intervall
    {
      intervall(T min, T max) : min(min), max(max) {}
    
      bool ist_enthalten(T c) const
      {
        assert(min <= max && "grenzen falsch");
        return c >= a && c <= b;
      }
    
      T min;
      T max;
    };
    

    Die C++0x Lösung. Warum einfach wenns auch umständlich geht^^

    Was hat das denn mit C++0x zu tun?
    Dieses Klassen-Template ist nunmal die Abbildung des Konzepts "Intervall".
    In diesem Fall ist das vielleicht ein bissel Overkill aber sonst lohnt es sich, den Dingen in Form von Funktionen oder Klassen einen verständlichen Namen zu geben. Abstraktion ist gut. Damit bekommt man auch größere Projekte besser in den Griff.

    kk


  • Mod

    Shade Of Mine schrieb:

    Die intervall Funktionmacht aber durchaus Sinn.

    Dann doch lieber gleich eine ganze Klasse für Intervalle die dann auch gleich mathematische Funktionen wie Vereinigung oder Schnitt kennt. Und halt eben noch eine kleine Funktion um festzustellen, ob ein Wert im Intervall ist.



  • Gut vorstellen könnte ich mir auch eine Intervall-Containerklasse mit STL-typischem Interface, die intern nur Start, Ende und Schrittweite speichert. Die Anwendungsfälle sind bestimmt nicht omnipräsent, aber wäre sicher manchmal ganz praktisch.



  • ipsec schrieb:

    Gut vorstellen könnte ich mir auch eine Intervall-Containerklasse mit STL-typischem Interface, die intern nur Start, Ende und Schrittweite speichert. Die Anwendungsfälle sind bestimmt nicht omnipräsent, aber wäre sicher manchmal ganz praktisch.

    So etwaas gibt es glaube ich schon:
    http://de.wikibooks.org/wiki/C%2B%2B-Programmierung/_Die_STL/_Algorithmen#Intervalle.2C_Sequenzen_und_Bereiche



  • intervall schrieb:

    Gibt es in der STL bereits eine Funktion ob sich eine Zahl in einem Intervall befindet?

    Zum Beispiel die Zahl 5 im Intervall 1 bis 10 befindet?

    bei boost gibt es so etwas

    #include <iostream>
    #include <boost/numeric/interval.hpp>
    
    int main()
    {
        using namespace std;
        boost::numeric::interval< int > bereich(1,10);
        for( int zahl; cin >> zahl; )
            cout << zahl << " liegt " << (in( zahl, bereich )? "": "nicht ") << "im Bereich [" << bereich.lower() << ";" << bereich.upper() << "]" << endl;
        return 0;
    }
    


  • SeppJ schrieb:

    Shade Of Mine schrieb:

    Die intervall Funktionmacht aber durchaus Sinn.

    Dann doch lieber gleich eine ganze Klasse für Intervalle die dann auch gleich mathematische Funktionen wie Vereinigung oder Schnitt kennt. Und halt eben noch eine kleine Funktion um festzustellen, ob ein Wert im Intervall ist.

    Ich sehe den Zusammenhang nicht. Eine "in_range()" Funktion habe ich selber oft. Wie man 2 Mengen vereinigen oder schneiden können soll ist mir hier aber erstmal ein Rätsel. Dazu braucht man ja erstmal eine Mengendefinition. Das ist ja wieder ein komplett anderes Thema.



  • Die Vereinigung von zwei Intervallen ist in der Regel nicht wieder ein Intervall (Intervalle bilden einen Halbring. Hat Wahrscheinlichkeitstheorie I doch was genützt.) Und beim Schnitt haben wir das kleine Problem, dass wir dann auch leere Intervalle zulassen müssen. Das kann z.B. die Definition von unskilled nicht.



  • Werner Salomon schrieb:

    intervall schrieb:

    Gibt es in der STL bereits eine Funktion ob sich eine Zahl in einem Intervall befindet?

    Zum Beispiel die Zahl 5 im Intervall 1 bis 10 befindet?

    bei boost gibt es so etwas

    #include <iostream>
    #include <boost/numeric/interval.hpp>
    
    int main()
    {
        using namespace std;
        boost::numeric::interval< int > bereich(1,10);
        for( int zahl; cin >> zahl; )
            cout << zahl << " liegt " << (in( zahl, bereich )? "": "nicht ") << "im Bereich [" << bereich.lower() << ";" << bereich.upper() << "]" << endl;
        return 0;
    }
    

    Weißt du ob man dabei auch ob/wie man offene/geschlossene intervalle bestimmen kann? Das wäre nämlich genau das was ich gebrauchen könnte.



  • intervall schrieb:

    Weißt du ob man dabei auch ob/wie man offene/geschlossene intervalle bestimmen kann? Das wäre nämlich genau das was ich gebrauchen könnte.

    in boost.interval ist jedes Intervall immer ein geschlossenes Intervall.

    Gruß
    Werner


  • Mod

    player4245 schrieb:

    Die C++0x Lösung. Warum einfach wenns auch umständlich geht^^

    ach was

    [](int l, int r, int x) { return l < x && x < r; } ( 1, 10, 5 );
    

    Ich nehm mal an, dass dass so ungefähr korrekt ist.


Anmelden zum Antworten