加速C ++:练习6-1 [英] Accelerated C++: exercise 6-1

查看:49
本文介绍了加速C ++:练习6-1的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有人熟悉本书?


加速C ++的练习6-1要求我们重新实现frame()和hcat()

操作使用迭代器。我已经在下面发布了我的答案,但是我想知道如果我在这里偏离轨道,那么



首先,这本书在第5章一直很活跃但是合理,然后突然间,它爆炸了。我不得不咬牙切齿地通过第6章,

但是第6章的练习非常温顺。


其次,看到它是令人惊讶的将行分为单词的函数

蒸发成一个非常小且容易理解的代码片段。我不会在6-1的答案中看到发生这种情况。我的迭代器版本不要等b $ b看起来更高效或更少杂乱。


如果有人熟悉这本书,我将不胜感激听到评论

关于我的答案是否在正确的轨道上,或者我是否错过了演习的

点。


谢谢!

Pete


//包含字符串(索引)的两个向量的水平连接

//

vector< string>

oldhcat(const vector< string>& left,const vector< string>& right)

{

vector< string> ret;


//添加一个在图片之间留一个空格。

vector< string> :: size_type width1 = maxWidth(left)+ 1;


vector< string> :: size_type i = 0,j = 0; //我:对,j:离开


//继续,直到我们看到两张照片中的所有行。

while(i!= left .size()|| j!= right.size())

{

string s;


//如果左边有一条线,把它复制到s。

if(i!= left.size())s = left [i ++];


s + = string(width1 - s.size(),''''); //填充到全宽


//如果有一条右边的行,请将其复制到s。

if(j!= right.size ())s + =对[j ++];


ret.push_back(s);

}


return ret;

}


//包含字符串(迭代器)的两个向量的水平连接

//

vector< string>

hcat(const vector< string>& left,const vector< string>& right)

{

vector< string> ret;


//添加一个在图片之间留一个空格。

vector< string> :: size_type width1 = maxWidth(left)+ 1;


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

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


//继续,直到我们看到两张图片中的所有行。

while(i!= left.end()|| j!= right.end())

{

string s;


//如果还有一行,请复制它是s。

if(i!= left.end())s = *(i ++);


s + = string(width1 - s。 size(),''''); //填充到全宽


//如果有一行右边,将其复制到s。

if(j!= right.end ())s + = *(j ++);


ret.push_back(s);

}


返回ret;

}


//在字符串向量周围放置一个框架(索引)

//

vector< string> oldframe(const vector< string>& v)

{

vector< string> ret;


string :: size_type maxlen = maxWidth(v); //最宽元素的宽度


//修复异常的零输入边界条件

int starNumber =(maxlen == 0)? 2:maxlen + 4;

字符串边框(starNumber,''*'');


ret.push_back(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(border); //底部边框

返回ret;

}


//在字符串向量周围放置一个框架(迭代器)< br $>
//

vector< string> frame(const vector< string>& v)

{

vector< string> ret;


string :: size_type maxlen = maxWidth(v); //最宽元素的宽度


//修复异常的零输入边界条件

int starNumber =(maxlen == 0)? 2:maxlen + 4;

字符串边框(starNumber,''*'');


ret.push_back(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(border); //底部边框


返回ret;

}

解决方案

Pete写道:

Accelerated C ++的练习6-1要求我们使用迭代器重新实现frame()和hcat()
操作。我已经在下面发布了我的答案,但我想知道
我是否在这里偏离轨道。

//包含字符串(索引)的两个向量的水平连接
//
vector< string>
oldhcat(const vector< string>& left,const vector< string>& right)
{
vector< string> ret;

//添加一个在图片之间留一个空格。
vector< string> :: size_type width1 = maxWidth(left)+ 1;

vector< string> :: size_type i = 0,j = 0; //我:对,j:离开

//继续,直到我们看到两张照片中的所有行。
while(i!= left.size()|| j! = right.size())
{
字符串s;

//如果有一行左边,将其复制到s。
if(i != left.size())s = left [i ++];

s + = string(width1 - s.size(),''''); //填充到全宽

//如果有一行右边,将其复制到s。
if(j!= right.size())s + = right [ j ++];

ret.push_back(s);


返回ret;
}



为什么不使用循环体的函数?为什么(考虑

你/ b $ b应该使用迭代器)你是否使用索引变量,并将它们命名为
和j?你的评论显示你也知道他们不是好名字。

使用left_iter和right_iter更容易。


HTH,
Michiel Salters

with i


迭代器版本很好;比索引器

版本简洁得多,但它们应该更快地执行(一点点)。对他们进行改进没有明显的方法

(除了可能更有用的变量名称......)。不过,在两种情况下,我都可能预先分配ret,然后通过另一个迭代器写入
,因为这样可以防止不必使用

每隔几次迭代重新分配一次内存。


Mi ************* @ tomtom.com 写道:

Pete写道:
< blockquote class =post_quotes> Accelerated C ++的练习6-1要求我们使用迭代器重新实现frame()和hcat()
操作。我已经在下面发布了我的答案,但我想知道
我是否在这里偏离轨道。

//包含字符串(索引)的两个向量的水平连接
//
vector< string>
oldhcat(const vector< string>& left,const vector< string>& right)
{
vector< string> ret;

//添加一个在图片之间留一个空格。
vector< string> :: size_type width1 = maxWidth(left)+ 1;

vector< string> :: size_type i = 0,j = 0; //我:对,j:离开

//继续,直到我们看到两张照片中的所有行。
while(i!= left.size()|| j! = right.size())
{
字符串s;

//如果有一行左边,将其复制到s。
if(i != left.size())s = left [i ++];

s + = string(width1 - s.size(),''''); //填充到全宽

//如果有一行右边,将其复制到s。
if(j!= right.size())s + = right [ j ++];

ret.push_back(s);


返回ret;
}


为什么不使用循环体的函数?为什么(考虑到
你应该使用迭代器)你是否使用索引变量,并将它们命名为
和j?你的评论显示你也知道他们不是好名字。
使用left_iter和right_iter更容易。




哦,我发布了函数的迭代器和索引版本。您引用的

是索引版本。 :)索引版本被命名为

" oldhcat()" (就像这个一样)和oldframe;迭代器版本是

" hcat()"和frame()。


Pete


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_type 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(border); // 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(border); // 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_type 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(border); // 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(border); // Bottom border

return ret;
}

解决方案

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


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.


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


这篇关于加速C ++:练习6-1的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆