How to code this with STL?

M

Milan Cermak

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
 
B

Bob Hairgrove

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 said:
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.
 
M

Milan Cermak

Bob said:
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
 
K

Klaus Eichner

Milan Cermak said:
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() );
}
 
P

Petec

Milan said:
Bob said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top