How to code this with STL?

Discussion in 'C++' started by Milan Cermak, Jun 6, 2004.

  1. Milan Cermak

    Milan Cermak Guest

    Hi all,
    I'm developing my own basic classes library (http://stlib.sf.net for
    those how are interested) and I'd like to compare its power to STL.
    Unfortunately I'm not familiar with STL - it blows up my mind everytime
    I try to understand it.

    Could you, please, show me the code implementing following functionality?

    Consider two strings that contains only digits. These strings are 7 to
    15 digits long. (They are telephone numbers read from text file.)
    These numbers are upper and lower limit of interval. How can I get a
    collection containing all numbers from this interval (including limits)?
    Resulting numbers should be also strings (textual representation of the
    number).
    Hint: The collection has maximally 100 items.

    I can do this in Smalltalk (which is the simpliest implementation):

    first := '420736300370'.
    last := '420736300399'.
    result := (first asNumber to: last asNumber)
    collect: [:num | num printString].

    I can do this also in C++ with my own library. I only need to get rid of
    very long numbers which I didn't implement yet. (That's where the hint
    becomes usefull.)

    Set *generateRoutesFromInterval(String *first, String *last)
    {
    Set *result;
    int firstUncommonIndex;
    String *commonPrefix;
    unsigned long firstNumber, lastNumber;

    result = new Set;
    for (firstUncommonIndex = 0;
    firstUncommonIndex < first->size();
    firstUncommonIndex++) {
    if (!first->at(firstUncommonIndex)->isEqual(last->at(firstUncommonIndex)))
    break;
    }
    commonPrefix = dynamic_cast<String *>(first->copy(0,
    firstUncommonIndex));
    firstNumber = dynamic_cast<String *>(first->copy(firstUncommonIndex,
    first->size()))->asNumber()->asUnsignedLong();
    lastNumber = dynamic_cast<String
    *>(last->copy(firstUncommonIndex,
    last->size()))->asNumber()->asUnsignedLong();
    for (; firstNumber <= lastNumber; firstNumber++) {
    char buffer[first->size()];
    sprintf(buffer, "%lu", firstNumber);
    result->add(&(*commonPrefix + buffer));
    }
    return result;
    }

    Could this be done with STL? How?

    Thanks to all who will spend their time on this task.
    Milan Cermak
     
    Milan Cermak, Jun 6, 2004
    #1
    1. Advertising

  2. On Sun, 06 Jun 2004 08:09:16 GMT, Milan Cermak <mcermak_@_chello_._cz>
    wrote:

    >Hi all,
    >I'm developing my own basic classes library (http://stlib.sf.net for
    >those how are interested) and I'd like to compare its power to STL.
    >Unfortunately I'm not familiar with STL - it blows up my mind everytime
    >I try to understand it.
    >
    >Could you, please, show me the code implementing following functionality?
    >
    >Consider two strings that contains only digits. These strings are 7 to
    >15 digits long. (They are telephone numbers read from text file.)
    >These numbers are upper and lower limit of interval. How can I get a
    >collection containing all numbers from this interval (including limits)?
    >Resulting numbers should be also strings (textual representation of the
    >number).
    >Hint: The collection has maximally 100 items.
    >
    >I can do this in Smalltalk (which is the simpliest implementation):
    >
    >first := '420736300370'.
    >last := '420736300399'.
    >result := (first asNumber to: last asNumber)
    > collect: [:num | num printString].
    >
    >I can do this also in C++ with my own library. I only need to get rid of
    >very long numbers which I didn't implement yet. (That's where the hint
    >becomes usefull.)


    I think it would be more efficient to convert the input into integers
    (perhaps long long or __int64 would be better, you can go to 18 digits
    that way, I believe), build the collection and convert the numbers
    back into strings instead of the way you propose. I would create a
    class TelephoneNumber which could take care of bounds checking and
    perhaps store the string representation and the actual number as
    member data. Use std::vector<TelephoneNumber> or
    std::list<TelephoneNumber> to hold the collection.

    >Set *generateRoutesFromInterval(String *first, String *last)
    >{
    > Set *result;
    > int firstUncommonIndex;
    > String *commonPrefix;
    > unsigned long firstNumber, lastNumber;
    >
    > result = new Set;
    > for (firstUncommonIndex = 0;
    > firstUncommonIndex < first->size();
    > firstUncommonIndex++) {
    > if (!first->at(firstUncommonIndex)->isEqual(last->at(firstUncommonIndex)))
    > break;
    > }
    > commonPrefix = dynamic_cast<String *>(first->copy(0,
    > firstUncommonIndex));
    > firstNumber = dynamic_cast<String *>(first->copy(firstUncommonIndex,
    > first->size()))->asNumber()->asUnsignedLong();
    > lastNumber = dynamic_cast<String
    >*>(last->copy(firstUncommonIndex,
    >last->size()))->asNumber()->asUnsignedLong();
    > for (; firstNumber <= lastNumber; firstNumber++) {
    > char buffer[first->size()];

    ^^^^^^^^^^^^^

    This will not compile -- you cannot declare arrays dynamically in C++.
    You need to use "new char[...]" (or std::string) instead.

    > sprintf(buffer, "%lu", firstNumber);
    > result->add(&(*commonPrefix + buffer));
    > }
    > return result;
    >}
    >
    >Could this be done with STL? How?


    You can do everything above with std::string.

    >Thanks to all who will spend their time on this task.
    >Milan Cermak


    --
    Bob Hairgrove
     
    Bob Hairgrove, Jun 6, 2004
    #2
    1. Advertising

  3. Milan Cermak

    Milan Cermak Guest

    Bob Hairgrove wrote:

    >> char buffer[first->size()];

    > ^^^^^^^^^^^^^
    >
    > This will not compile -- you cannot declare arrays dynamically in C++.
    > You need to use "new char[...]" (or std::string) instead.


    Fortunately it does. Using GCC 2.95.4. May be I'll need to fix it when
    I'll move to GCC 3.2+.

    Milan Cermak
     
    Milan Cermak, Jun 6, 2004
    #3
  4. "Milan Cermak" <mcermak_@_chello_._cz> wrote in message
    news:MiAwc.52813$...
    > Hi all,
    > I'm developing my own basic classes library (http://stlib.sf.net for
    > those how are interested) and I'd like to compare its power to STL.
    > Unfortunately I'm not familiar with STL - it blows up my mind everytime
    > I try to understand it.
    >
    > Could you, please, show me the code implementing following functionality?
    >
    > Consider two strings that contains only digits. These strings are 7 to
    > 15 digits long. (They are telephone numbers read from text file.)
    > These numbers are upper and lower limit of interval. How can I get a
    > collection containing all numbers from this interval (including limits)?
    > Resulting numbers should be also strings (textual representation of the
    > number).
    > Hint: The collection has maximally 100 items.
    >
    > I can do this in Smalltalk (which is the simpliest implementation):
    >
    > first := '420736300370'.
    > last := '420736300399'.
    > result := (first asNumber to: last asNumber)
    > collect: [:num | num printString].
    >
    > I can do this also in C++ with my own library. I only need to get rid of
    > very long numbers which I didn't implement yet. (That's where the hint
    > becomes usefull.)
    >
    > Set *generateRoutesFromInterval(String *first, String *last)
    > {
    > Set *result;
    > int firstUncommonIndex;
    > String *commonPrefix;
    > unsigned long firstNumber, lastNumber;
    >
    > result = new Set;
    > for (firstUncommonIndex = 0;
    > firstUncommonIndex < first->size();
    > firstUncommonIndex++) {
    > if (!first->at(firstUncommonIndex)->isEqual(last->at(firstUncommonIndex)))
    > break;
    > }
    > commonPrefix = dynamic_cast<String *>(first->copy(0,
    > firstUncommonIndex));
    > firstNumber = dynamic_cast<String *>(first->copy(firstUncommonIndex,
    > first->size()))->asNumber()->asUnsignedLong();
    > lastNumber = dynamic_cast<String
    > *>(last->copy(firstUncommonIndex,
    > last->size()))->asNumber()->asUnsignedLong();
    > for (; firstNumber <= lastNumber; firstNumber++) {
    > char buffer[first->size()];
    > sprintf(buffer, "%lu", firstNumber);
    > result->add(&(*commonPrefix + buffer));
    > }
    > return result;
    > }
    >
    > Could this be done with STL? How?


    One possible implementation would be to define an iterator class like so:

    // the following code is incomplete and untested
    // just to demonstrate the basic idea

    class walk_str_iterator
    {
    public:
    walk_str_iterator(std::string s) : wsi(s) {}
    bool operator==(const walk_str_iterator& x) const { return wsi == x.wsi; }
    bool operator!=(const walk_str_iterator& x) const { return wsi != x.wsi; }
    walk_str_iterator operator*() { return wsi; }
    walk_str_iterator& operator++() {
    // ...place here some of your code from the
    // generateRoutesFromInterval() function to calculate the next
    position...
    }
    private:
    std::string wsi;
    }

    class print_wsi {
    public:
    void operator() (const walk_str_iterator& w) { std::cout << *w <<
    std::endl; }
    }

    // ===========================
    // you could then use the STL like so...

    int main()
    {
    walk_str_iterator first ("420736300370");
    walk_str_iterator last ("420736300399");
    std::for_each(first, last, print_wsi() );
    }

    >
    > Thanks to all who will spend their time on this task.
    > Milan Cermak
    >
     
    Klaus Eichner, Jun 6, 2004
    #4
  5. Milan Cermak

    Petec Guest

    Milan Cermak wrote:
    > Bob Hairgrove wrote:
    >
    >>> char buffer[first->size()];

    >> ^^^^^^^^^^^^^
    >>
    >> This will not compile -- you cannot declare arrays dynamically in
    >> C++. You need to use "new char[...]" (or std::string) instead.

    >
    > Fortunately it does. Using GCC 2.95.4. May be I'll need to fix it when
    > I'll move to GCC 3.2+.
    >
    > Milan Cermak


    But it's not standard C++, the topic of this group. Please leave your
    compiler-specific extensions out of here.

    A standard solution:

    #include <vector>
    ....
    std::vector<char> buffer(first->size());
    ....

    - Pete
     
    Petec, Jun 6, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Allan Bruce

    To STL or not to STL

    Allan Bruce, Oct 16, 2003, in forum: C++
    Replies:
    41
    Views:
    1,066
    Christopher Benson-Manica
    Oct 17, 2003
  2. Replies:
    4
    Views:
    805
    Daniel T.
    Feb 16, 2006
  3. Replies:
    2
    Views:
    556
    klaus hoffmann
    Feb 22, 2006
  4. Replies:
    5
    Views:
    507
    Markus Schoder
    Apr 16, 2006
  5. Steve
    Replies:
    2
    Views:
    507
    Andre Kostur
    Nov 6, 2007
Loading...

Share This Page