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

我的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 themedian function that we wrote in §8.1.1/140 passes thevector by value. Could we rewrite themedian function to operate on iterators instead of passing thevector? 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 callswap 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 avector<string>. Test these new versions by writing programs that attach the output iterator directly to the standard output, and by storing the results in alist<string> and avector<string>.

Ans:见Github。

8-6. Suppose that m has type map<int, string>, and that we encounter a call tocopy(m.begin(), m.end(), back_inserter(x)). What can we say about the type ofx? What if the call werecopy(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 complicatedbegin + (end - begin) /2?

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

iter+n;

n+iter;

iter1-iter2

而不存在两个迭代器相加的操作定义。

你可能感兴趣的:(C++,C++,Accelerated,Accelerated,C++习题解答,通过示例进行编程实践)