您的位置:首页 > 编程语言 > C语言/C++

Accelerated C++:通过示例进行编程实践——练习解答(第8章)

2014-10-25 01:22 375 查看
我的Github地址:https://github.com/lanbeilyj/Accerlerated-C-plus-plus

8-0. Compile, execute, and test the programs in this chapter.

#include <string>
#include <iostream>
#include <cctype>
#include <algorithm>
#include <iterator>
using namespace std;

bool space(char c)
{
return isspace(c);
}

bool not_space(char c)
{
return !isspace(c);
}

template <class out>
void split(const string& s, out os)
{
typedef string::const_iterator iter;
iter i=s.begin();
iter e=s.end();
while(i!=e)
{
i=find_if(i,e,not_space);
iter j=find_if(i,e,space);
if(i!=e)
{
*os++=string(i,j);
}
i=j;
}
}

int main()
{
string s;
while(getline(cin,s))
//the ostream_iterator connect to os,and assign string to os actually assigned to this ostream_iterator
split(s,ostream_iterator<string>(cout,"\n"));
return 0;
}


8-1. Note that the various
analysis
functions we wrote in §6.2/110 share the same behavior; they differ only in terms of the functions they call to calculate the final grade. Write a template function, parameterized by the type
of the grading function, and use that function to evaluate the grading schemes.

Ans:见Github。

8-2. Implement the following library algorithms, which we used in Chapter 6 and described in §6.5/121. Specify what kinds of iterators they require. Try to minimize the number of distinct iterator operations that each function requires.
After you have finished your implementation, see §B.3/321 to see how well you did.

equal(b, e, d)                 search(b, e, b2, e2)
find(b, e, t)                  find_if(b, e, p)
copy(b, e, d)                  remove_copy(b, e, d, t)
remove_copy_if(b, e, d, p)     remove(b, e, t)
transform(b, e, d, f)          partition(b, e, p)
accumulate(b, e, t)


这里我实现了除练习外,总共17个模板库的实现,而详细的测试以及源码,见Github。
1.max(x,y)
template <class T>
T max(const T& x,const T& y)
{
return x<y?y:x;
}
2.find(b,e,t)
template <class In,class X>
In find(In begin,In end,const X& x)
{
//In is an iterator or const_iterator
while(begin!=end && *begin!=x)
++begin;
return begin;
}
3.find_if(b,e,p)
template <class In>
In find_if(In begin,In end,p)
{
while(begin!=end)
{
if(p(*begin))
{
return begin;
}
++begin;
}
}
4.search(b,e,b2,e2)
template <class In>
In search(In b,In e,In b2,In e2)
{
int k=0;
In start;
while(b2!=e2)
{
while(b!=e)
{
if(k==0 && *b==*b2)
{
start=b;
++b;
++k;
break;
}
else if(*b==*b2)
{
++b;
break;
}
++b;
}
++b2;
}
return start;
}
5.remove(b,e,t)
//put the element that are !=t in front of the container
template <class X>
void sw(X& x,X& y)
{
X temp=x;
x=y;
y=temp;
}
template <class In,class X>
In remove(In begin,In end,X& x)
{
while(begin!=end)
{
if(*begin==x)
{
--end;
while(*end==x)
--end;

sw(*begin,*end);
}
++begin;
}
return end;
}
6.copy(b,e,d)
template <class In,class Out>
Out copy(In begin,In end,Out dest)
{
while(begin!=end)
*dest++=*begin++;
return dest;
}
7.remove_copy(b,e,d,t)
template <class In,class Out,class X>
Out remove_copy(In begin,In end,Out dest,const X& x)
{
while(begin!=end)
{
if(*begin==x)
*d++=*begin;
++begin;
}
return dest;
}
8.remove_copy_if(b,e,d,p)
template <class X>
bool fun(const X& x)
{
return *x>10;
}
template <class In,class Out>
Out remove_copy_if(In begin,In end,Out dest,bool fun(const In&))
{
while(begin!=end)
{
if(!fun(begin))
*dest++=*begin;

++begin;
}
return dest;
}
9.replace(b,e,x,y)
template <class In,class X>
void replace(In begin,In end,const X& x,const X& y)
{
while(begin!=end)
{
if(*begin==x)
*begin=y;
++begin;
}
}
10.swap(x,y)
template <class X>
void swap(X& x,X& y)
{
X temp;
temp=x;
x=y;
y=temp;
}
11.reverse
template <class In>
void reverse(In begin,In end)
{
while(begin!=end)
{
--end;
if(begin!=end)
{
swap(*begin++,*end);
}
}
}
12.binary_search
template <class In,class X>
In binary_search(In begin,In end,const X& x)
{
//the function is return a iterator,and if not find
//we let it return the second arguments(end)
while(begin!=end)
{
In mid=begin+(end-begin)/2;
if(*mid<x)
end=mid;
else if(x<*mid)
begin=mid+1;
else
return mid;
}
return end;
}
13.split
/*
bool space(char c)
{
return isspace(c);
}
bool not_space(char c)
{
return !isspace(c);
}
*/
template <class Out>
void split(const string& s,Out os)
{
typedef string::const_iterator iter;
iter i=s.begin();
iter e=s.end();
while(i!=e)
{
i=find_if(i,e,not_space);
iter j=find_if(i,e,space);
if(i!=e)
*os++=string(i,j);
i=j;
}
}
14.equal(b,e,b2)
template <class In>
bool equal(In beg,In end,In beg2)
{
while(beg!=end)
{
if(*beg!=*beg2)
{
return false;
}
++beg;
++beg2;
}
return true;
}
15.transform(b,e,d,f)
template <class In,class Out>
Out transform(In beg,In end,Out beg2,,bool fun(In))
{
while(beg!=end)
{
if(fun(beg))
{
*beg2=*beg;
++beg;
}
++beg2;
++beg;
}
}
16.partition(b,e,p)
/*
*b,e is a bothway iterator;if p return true put the elements into the former of the container,else into the later;
*return a iterator direct to the first dissatified elements.
*/
template <class Y>
bool fun(Y& x)
{
return *x<6;
}
template <class X>
void sw(X& x,X& y)
{
X temp=x;
x=y;
y=temp;
}
template <class In>
In partition(In beg,In end,bool fun(In&))
{
while(beg!=end)
{
while(fun(beg))
{
++beg;
if(beg==end)
return beg;
}

do{
--end;
if(beg==end)
return beg;
}while(!fun(end));

sw(*beg,*end);
++beg;
}
return beg;
}
17.accumulate(b,e,t)
template <class In,class X>
X accumulate(In beg,In end,X x)
{
while(beg!=end)
{
x+=*beg;
++beg;
}
return x;
}


8-3. As we learned in §4.1.4/58, it can be expensive to return (or pass) a container by value. Yet the
median
function that we wrote in §8.1.1/140 passes the
vector
by value. Could we rewrite the
median

function to operate on iterators instead of passing the
vector
? If we did so, what would you expect the performance impact to be?

Ans:不可以,用迭代器代替向量,会导致students记录被修改的不安全隐患,且修改量大;修改后避免了按值传递当处理当量数据时会提升性能。

8-4. Implement the
swap
function that we used in §8.2.5/148. Why did we call
swap
rather than exchange the values of
*beg
and
*end
directly?
Hint: Try it and see.

Ans:见Github。

8-5. Reimplement the
gen_sentence
and
xref
functions from Chapter 7 to use output iterators rather than writing their output directly to a
vector<string>
. Test these new versions by writing programs
that attach the output iterator directly to the standard output, and by storing the results in a
list<string>
and a
vector<string>
.

Ans:见Github。

8-6. Suppose that
m
has type
map<int, string>
, and that we encounter a call to
copy(m.begin(), m.end(), back_inserter(x))
. What can we say about the type of
x
? What if the call were
copy(x.begin(),
x.end(), back_inserter(m))
instead?

Ans:对于back_inserter()其参数要求为一个容器,以利用该容器产生一个迭代器,然后该迭代器可以给该容器插入新的元素;故需该容器需要满足条件是:

支持list、vector和string都支持的push_back()操作。由上分析可知对于map容器其并不支持push_back()操作,故cpoy(x.begin(),x.end(),back_inserter(m))不可能运行。

8-7. Why doesn't the
max
function use two template parameters, one for each argument type?

Ans:max比较大小是需要两个元素具有相同类型的。

8-8. In the
binary_search
function in §8.2.6/148, why didn't we write
(begin + end) / 2
instead of the more complicated
begin + (end - begin) /2
?

Ans:迭代器支持的操作如下:

iter+n;

n+iter;

iter1-iter2

而不存在两个迭代器相加的操作定义。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐