473,669 Members | 2,471 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Accelerated C++: exercise 6-1

Is anyone familiar with this book?

Exercise 6-1 of Accelerated C++ asks us to reimplement the frame() and hcat()
operations using iterators. I've posted my answers below, but I'm wondering
if I'm off track here.

First of all, the book has been brisk but reasonable up to chapter 5, and
then suddenly, it exploded. I had to grit my teeth to get through chapter 6,
but the exercises for chap 6 are pretty tame.

Secondly, it was astonishing to see the function that splits lines into words
evaporate into a really small and easily understandable piece of code. I
don't see that happening in my answers to 6-1. My iterator versions don't
look any more efficient or less cluttered.

If anyone is familiar with this book, I would appreciate hearing comments
about whether my answers are on the right track or whether I've missed the
point of the exercise.

Thanks!
Pete


// Horizontal concatenation of two vectors containing strings (indexes)
//
vector<string>
oldhcat( const vector<string> &left, const vector<string> &right )
{
vector<string> ret;

// Add one to leave a space between the pictures.
vector<string>: :size_type width1 = maxWidth(left) + 1;

vector<string>: :size_type i = 0, j = 0; // i: right, j: left

// Continue until we've seen all rows from both pictures.
while ( i != left.size() || j != right.size() )
{
string s;

// If there's a line of left, copy it to s.
if ( i != left.size() ) s = left[i++];

s += string(width1 - s.size(), ' '); // Pad to full width

// If there's a line of right, copy it to s.
if ( j != right.size() ) s += right[j++];

ret.push_back(s );
}

return ret;
}

// Horizontal concatenation of two vectors containing strings (iterators)
//
vector<string>
hcat( const vector<string> &left, const vector<string> &right )
{
vector<string> ret;

// Add one to leave a space between the pictures.
vector<string>: :size_type width1 = maxWidth(left) + 1;

vector<string>: :const_iterator i = left.begin();
vector<string>: :const_iterator j = right.begin();

// Continue until we've seen all rows from both pictures.
while ( i != left.end() || j != right.end() )
{
string s;

// If there's a line of left, copy it to s.
if ( i != left.end() ) s = *(i++);

s += string(width1 - s.size(), ' '); // Pad to full width

// If there's a line of right, copy it to s.
if ( j != right.end() ) s += *(j++);

ret.push_back(s );
}

return ret;
}

// Put a frame around a vector of strings (indexes)
//
vector<string> oldframe( const vector<string> &v )
{
vector<string> ret;

string::size_ty pe maxlen = maxWidth(v); // width of widest element

// Fix the anomalous zero-input border condition
int starNumber = ( maxlen == 0 ) ? 2 : maxlen + 4;
string border( starNumber, '*' );

ret.push_back(b order); // Top border

for ( vector<string>: :size_type i = 0; i != v.size(); ++i )
ret.push_back(" * " + v[i] + string(maxlen - v[i].size(), ' ') + " *");

ret.push_back(b order); // Bottom border
return ret;
}

// Put a frame around a vector of strings (iterators)
//
vector<string> frame( const vector<string> &v )
{
vector<string> ret;

string::size_ty pe maxlen = maxWidth(v); // width of widest element

// Fix the anomalous zero-input border condition
int starNumber = ( maxlen == 0 ) ? 2 : maxlen + 4;
string border( starNumber, '*' );

ret.push_back(b order); // Top border

vector<string>: :const_iterator iter;
for ( iter = v.begin(); iter != v.end(); ++iter )
ret.push_back(" * " + *iter + string(maxlen - iter->size(), ' ') + " *");

ret.push_back(b order); // Bottom border

return ret;
}
Dec 28 '05 #1
14 3089
Pete wrote:
Exercise 6-1 of Accelerated C++ asks us to reimplement the frame() and hcat()
operations using iterators. I've posted my answers below, but I'm wondering
if I'm off track here.

// Horizontal concatenation of two vectors containing strings (indexes)
//
vector<string>
oldhcat( const vector<string> &left, const vector<string> &right )
{
vector<string> ret;

// Add one to leave a space between the pictures.
vector<string>: :size_type width1 = maxWidth(left) + 1;

vector<string>: :size_type i = 0, j = 0; // i: right, j: left

// Continue until we've seen all rows from both pictures.
while ( i != left.size() || j != right.size() )
{
string s;

// If there's a line of left, copy it to s.
if ( i != left.size() ) s = left[i++];

s += string(width1 - s.size(), ' '); // Pad to full width

// If there's a line of right, copy it to s.
if ( j != right.size() ) s += right[j++];

ret.push_back(s );
}

return ret;
}


Why don't you use a function for the loop body? And why (considering
you
should be using iterators) do you use index variables, and name them i
and j? Your comment shows you too know they're not good names.
It's easier to use left_iter and right_iter.

HTH,
Michiel Salters
with i

Dec 28 '05 #2
pH
The iterator versions are fine; not much more concise than the indexer
version, but they should perform (a bit) faster. There's no obvious way
of improving on them (except perhaps more helpful variable names...). I
would probably pre-allocate ret, though, in both cases, and then write
to that through another iterator, as that would prevent having to
re-allocate the memory for ret every few iterations.

Dec 28 '05 #3
Mi************* @tomtom.com wrote:
Pete wrote:
Exercise 6-1 of Accelerated C++ asks us to reimplement the frame() and hcat()
operations using iterators. I've posted my answers below, but I'm wondering
if I'm off track here.

// Horizontal concatenation of two vectors containing strings (indexes)
//
vector<string>
oldhcat( const vector<string> &left, const vector<string> &right )
{
vector<string> ret;

// Add one to leave a space between the pictures.
vector<string>: :size_type width1 = maxWidth(left) + 1;

vector<string>: :size_type i = 0, j = 0; // i: right, j: left

// Continue until we've seen all rows from both pictures.
while ( i != left.size() || j != right.size() )
{
string s;

// If there's a line of left, copy it to s.
if ( i != left.size() ) s = left[i++];

s += string(width1 - s.size(), ' '); // Pad to full width

// If there's a line of right, copy it to s.
if ( j != right.size() ) s += right[j++];

ret.push_back(s );
}

return ret;
}


Why don't you use a function for the loop body? And why (considering
you
should be using iterators) do you use index variables, and name them i
and j? Your comment shows you too know they're not good names.
It's easier to use left_iter and right_iter.


Oh, I had posted both the iterator and index versions of the functions. The
one you quoted is the index version. :) The index versions were named
"oldhcat()" (as this one is) and "oldframe"; the iterator versions were
"hcat()" and "frame()".

Pete
Dec 28 '05 #4
On 2005-12-28, Pete <no****@ucdavis .edu> wrote:
Is anyone familiar with this book?

Exercise 6-1 of Accelerated C++ asks us to reimplement the
frame() and hcat() operations using iterators. I've posted my
answers below, but I'm wondering if I'm off track here.

First of all, the book has been brisk but reasonable up to
chapter 5, and then suddenly, it exploded. I had to grit my
teeth to get through chapter 6, but the exercises for chap 6
are pretty tame.

Secondly, it was astonishing to see the function that splits
lines into words evaporate into a really small and easily
understandable piece of code. I don't see that happening in my
answers to 6-1. My iterator versions don't look any more
efficient or less cluttered.
You need to change the signature of the iterator versions so that
you receive input iterators and write to an output iterator.
// Horizontal concatenation of two vectors containing strings (iterators)
//
vector<string>
hcat( const vector<string> &left, const vector<string> &right )


I believe you instead need something like this as your function
signature:

template <class In, class Out>
Forward
hcat(In left_begin, In left_end, In right_begin, In right_end, Out output)

Start with that and see if you get more felicitous results.

--
Neil Cerutti
Jan 2 '06 #5

Neil Cerutti wrote:
You need to change the signature of the iterator versions so that
you receive input iterators and write to an output iterator.
// Horizontal concatenation of two vectors containing strings (iterators)
//
vector<string>
hcat( const vector<string> &left, const vector<string> &right )


I believe you instead need something like this as your function
signature:

template <class In, class Out>
Forward
hcat(In left_begin, In left_end, In right_begin, In right_end, Out output)

Start with that and see if you get more felicitous results.


Sound advice in general, but in the context of the Accelerated C++
book, the OP hasn't encountered writing your own generic functions yet.
That's in chapter 8.

Gavin Deane

Jan 2 '06 #6

Pete wrote:
Secondly, it was astonishing to see the function that splits lines into words
evaporate into a really small and easily understandable piece of code. I
don't see that happening in my answers to 6-1. My iterator versions don't
look any more efficient or less cluttered.


The string splitting function didn't evaporate into a concise piece of
code by substituting iterators for indices. It did it by substituting
standard algorithms function calls for hand-coded loops.

As you have found, just changing from indices to iterators does not
necessarily make the code more concise. But it does mean that, when the
opportunity arises, you are able to interface with the standard
library's algorithms - something that code using indices can't do.

Gavin Deane

Jan 2 '06 #7
On 28 Dec 2005 04:26:04 +0100, Pete <no****@ucdavis .edu> wrote:
First of all, the book has been brisk but reasonable up to chapter 5, and
then suddenly, it exploded. I had to grit my teeth to get through chapter 6,
It's not a gentle introduction to C++ programming but an 'accelerated'
intruduction to STL programming.
vector<strin g>
oldhcat( const vector<string> &left, const vector<string> &right ) [...]vector<strin g>
hcat( const vector<string> &left, const vector<string> &right ) [...]vector<strin g> oldframe( const vector<string> &v ) [...]vector<strin g> frame( const vector<string> &v )

[...]

Returning a vector<somethin g> _by value_ is always bad style. You
should pass an empty vector by reference.

Best wishes,
Roland Pibinger
Jan 2 '06 #8
In article <43************ **@news.utanet. at>,
Roland Pibinger <rp*****@yahoo. com> wrote:
Returning a vector<somethin g> _by value_ is always bad style. You
should pass an empty vector by reference.


False. That is often a reasonable solution (though be careful about
module boundaries). Like most generalizations , however, your "always"
is simply not true.
--
Mark Ping
em****@soda.CSU A.Berkeley.EDU
Jan 2 '06 #9
On Mon, 2 Jan 2006 21:49:11 +0000 (UTC), em****@soda.csu a.berkeley.edu
(E. Mark Ping) wrote:
In article <43************ **@news.utanet. at>,
Roland Pibinger <rp*****@yahoo. com> wrote:
Returning a vector<somethin g> _by value_ is always bad style. You
should pass an empty vector by reference.


False. That is often a reasonable solution (though be careful about
module boundaries). Like most generalizations , however, your "always"
is simply not true.


One real world example where returning a vector by value is a
'reasonable solution'?
Jan 2 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
7910
by: Martin | last post by:
I am reading through Koenig and Moo's "Accelerated C++" and attempting the exercises. Are there any sample solutions somewhere? It's all very well me doing a solution, which seems to work, but for all I know it can be riddled with undefined behaviours and bad C++. The alternative is to post my solution to every single exercise and ask for guidance, but I actually think that is counter-productive and tantamount to spamming anyway. A set of...
3
3382
by: Frankie Montenegro | last post by:
Hi everyone, I must say that, even though I think that Accelerated C++ by Koenig and Moo is an awesome text, the wording of exercises is very poor. I spend half the time just trying to figure out what is it they want me to do. Anyway, I somehow managed untill chapter 5 but now I am hopelessly stuck. But I am completely lost with the wording of the following three exercises: 5-2.
1
2716
by: utab | last post by:
Hi there, I have been reading Accelerated C++ by Andrew Koenig which is an excellent way of learning C++ from even the first pages by using the standard library. One drawback is that no answers to nice exercise sets. Is there anyone who could provide the answers of the exercises in the book? Or an URL will be very much appreciated.
3
1918
by: utab | last post by:
Exercise 5.10 from Accelerated C++ by Andrew Koenig Palindromes are words that are spelled the same right to left as left to right. Write a program to find all the palindromes in a dictionary. Next, find the longest palindrome. How do u think you can supply a dictionary to a program? The examples are real world problems I have to accept :( but they must be in the context of a newcomer can cope and learn without discourage. This is my...
8
4711
by: utab | last post by:
Dear all, in a container example, this question is asked in exercises in Accelerated C++ page 154, 8.8? why dont we use (begin+end)/2 instead of begin + (end - begin) / 2 is that someting related with the algortihm if you take a vector lets say begin end (one past the last) | | 1 2 3 4 4 6 7 8 9
10
3251
by: Xernoth | last post by:
Hi, This is my first post here, so please be gentle. I've been studying c+ + by mostly using the book Accelerated C++ by Andrew Koenig and Barbara E. Moo. So far, I've been picking things up all right, and I've come to an exercise 3-2 that requires the following: 3-2. Write a program to compute and print the quartiles (that is, the quarter of the numbers with the largest values, the next highest
0
1062
by: Lambda | last post by:
I'm trying to complete all the exercises of Accelerated C++. I'm not sure what does the exercise 5-5 mean. And how about 5-9? Thanks
0
1154
by: Lambda | last post by:
It's from the Accelerated C++ exercise 8-1 The old version is based on pointer to function: double analysis(const std::vector<Student_info>& students, double analysis_grade(const Student_info& s)) { vector<doublegrades; transform(students.begin(), students.end(),
8
1840
by: utab | last post by:
Dear all, In a question in the highly recommended book Accelerated C++, it is asked to change a const function into a plain function. After on the reader is expected to find which function(s) should change. The function to change is original version std::string name() const { return n; }
0
8465
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8894
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8803
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8587
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
5682
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4206
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4384
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2792
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2029
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.