Basis eines Vectors ändern



  • Hallo,

    kann mir jemand sagen, ob man die Basis eines STL-Vectors ändern kann (wie es bei Boost-Multiarray mit boost::multi_array_types::extent_range möglich ist)?

    Falls das nicht geht: Wie bekommt man dann Vektoren mit Basis ungleich 0?


  • Administrator

    Sowas ist nicht möglich bei std::vector .

    ingobulla schrieb:

    Falls das nicht geht: Wie bekommt man dann Vektoren mit Basis ungleich 0?

    Indem du einen Offset speicherst? Könntest zum Beispiel die Klasse std::vector kapseln.

    Grüssli



  • Dravere schrieb:

    Indem du einen Offset speicherst? Könntest zum Beispiel die Klasse std::vector kapseln.

    Gibt es da gar keine Standardlösung (in der Boost wurde ich nicht fündig)?

    Das Problem scheint mir doch sehr elementar und ich möchte ungern etwas selber schreiben und dann irgendwann feststellen, dass es das Ganze schon irgendwo einigermaßen standartisiert gibt.


  • Administrator

    ingobulla schrieb:

    Das Problem scheint mir doch sehr elementar ...

    Wie bitte? Elementar? Es ist simpel vielleicht, aber definitiv nicht elementar. Sowas braucht man nur in Spezialfällen und vor allem ist es nicht die Aufgabe eines Containers, eine solche Funktionalität anzubieten.
    Wozu brauchst du es denn?

    Grüssli



  • ingobulla schrieb:

    Gibt es da gar keine Standardlösung (in der Boost wurde ich nicht fündig)?

    Das Problem scheint mir doch sehr elementar und ich möchte ungern etwas selber schreiben und dann irgendwann feststellen, dass es das Ganze schon irgendwo einigermaßen standartisiert gibt.

    Hm.... mir fällt jetzt nichts ein, warum ich das täglich brauchen würde, wieso kommst du auf die Idee, das sei ein Problem für das es eine Standardlösung geben muss? Was hast du denn genau vor, vielleicht gibt´s da einen anderen Ansatz?



  • DocShoe schrieb:

    Hm.... mir fällt jetzt nichts ein, warum ich das täglich brauchen würde, wieso kommst du auf die Idee, das sei ein Problem für das es eine Standardlösung geben muss? Was hast du denn genau vor, vielleicht gibt´s da einen anderen Ansatz?

    Nach meinem Empfinden kommt das in der Bioinformatik häufiger vor.

    Z. B. wenn man Pseudocode für einen Algorithmus hat (von einem Dritten), den man implementieren will, und dort mit Basis 1 gearbeitet wird. Man möchte ja, dass Pseudocode und C++-Code möglichst ähnlich sind (insbesondere will man, wenn man beide zusammen anschaut, nicht ständig im Kopf den Basiswechsel durchführen).

    Bei mir jetzt konkret ist es was anderes: Ich habe in meinem Programm eine Genomsequenz (für Fachfremde: das ist abstrakt betrachtet einfach ein String) und möchte eine (eigene) Funktion auf - sagen wir - Position 1000 bis 2000 anwenden. Diese Funktion verwendet ein 1-dim. Array dessen Index der Position entspricht (im wesentlichen bildet das Array jede Position auf einen Integer ab). Da würde ich auch gerne die durch das Problem kanonisch gegebene Indizierung von 1000 bis 2000 verwenden.


  • Administrator

    ingobulla schrieb:

    Z. B. wenn man Pseudocode für einen Algorithmus hat (von einem Dritten), den man implementieren will, und dort mit Basis 1 gearbeitet wird. Man möchte ja, dass Pseudocode und C++-Code möglichst ähnlich sind (insbesondere will man, wenn man beide zusammen anschaut, nicht ständig im Kopf den Basiswechsel durchführen).

    Ehm, wie bitte? Du verkomplizierst deinen C++ Code, damit er mit Pseudo-Code übereinstimmt? <lang-gezogen>ok</lang-gezogen>

    ingobulla schrieb:

    Bei mir jetzt konkret ist es was anderes: Ich habe in meinem Programm eine Genomsequenz (für Fachfremde: das ist abstrakt betrachtet einfach ein String) und möchte eine (eigene) Funktion auf - sagen wir - Position 1000 bis 2000 anwenden. Diese Funktion verwendet ein 1-dim. Array dessen Index der Position entspricht (im wesentlichen bildet das Array jede Position auf einen Integer ab). Da würde ich auch gerne die durch das Problem kanonisch gegebene Indizierung von 1000 bis 2000 verwenden.

    Wäre dazu nicht eher das Iteratoren- oder Range-Konzept geeignet? Du kannst zum Beispiel alle Algorithmen aus der Standardbibliothek auf einen kleineren Bereich eines Containers anwenden, ohne die Basis zu wechseln.

    Grüssli



  • Dann bau dir doch einfach einen Wrapper, der den string/vector/was auch immer umschliesst und intern eine Offsetkorrektur durchführt. Ob das allerdings praktikabel und notwendig ist ... das soll der Bioinformatiker entscheiden :p
    Spätestens bei Iteratoren wird´s etwas unübersichtlich...

    Edit:
    Obwohl... die Iteratoren müssen ja nicht angefasst werden, da begin()/end() immer den Anfang oder das Ende kennzeichnen... hab´s mal ergänzt. Da fehlen jetzt natürlich immer noch einige Methoden, um vollständige Transparenz zu implementieren (size/empty/clear/etc.), ob das den Aufwand wirklich wert ist, nur um Konformität mit einem PSEUDO-CODE zu erreichen...

    class StringView
    {
    	std::string& 	Data_;
    	std::size_t 	Offset_;
    
    public:
       StringView( std::string& Data ) :
          Data_( Data ), Offset_( 0 )
       {
       }
    
       StringView( std::string& Data, std::size_t Offset ) :
          Data_( Data ), Offset_( Offset )
       {
       }
    
       std::string::reference operator[]( size_t Index )
       {
          return Data_[Index + Offset_];
       }
    
       std::string::const_reference operator[]( size_t Index ) const
       {
          return Data_[Index + Offset_];
       }
    
       std::string::iterator begin()
       {
          return Data_.begin();
       }
    
       std::string::const_iterator begin() const
       {
          return Data_.begin();
       }
    
       std::string::iterator end()
       {
          return Data_.end();
       }
    
       std::string::const_iterator end() const
       {
          return Data_.end();
       }
    };
    
    int main()
    {
       std::string sequence = "1234567890";
    
       // Offset von -1 simuliert 1-basierten Zugriff
       StringView view( sequence, -1 );
    
       char c0 = view[1];
    }
    


  • Ich habe sowas noch nie gebraucht. Ich kann mir auch nicht vorstellen, warum das so nützlich sein sollte. Pseudo-Code-Kompatibilität sehe ich jedenfalls nicht als guten Grund an... 🙄

    Ich würde mir wenn überhaupt ein einzelnes (bzw. zwei, mit const -Überladung) freies Funktionstemplate schreiben, das einen verschobenen Zugriff ermöglicht. Eine ganze Wrapper-Klasse zu schreiben scheint mir übertrieben, ausserdem schränkt es die Flexibilität ein.

    Warum eigentlich "Basis"? Mir ist als erstes die Basis eines Vektorraums in den Sinn gekommen, und dann habe ich gedacht, du könntest die Dimension (Anzahl Verschachtelungen) meinen. Jedenfalls ist mir erst aufgrund der anderen Beiträge klar geworden, worum es sich handelt.



  • Nexus schrieb:

    Warum eigentlich "Basis"?

    Den Begriff "Basis" hab ich von hier (eingedeutscht): http://www.boost.org/doc/libs/1_38_0/libs/multi_array/doc/user.html#sec_base

    Daher kommt auch meine Annahme, ich sei nicht der einzige, der sowas braucht.


Anmelden zum Antworten