《Accelerated C++》导读(Chapter 6)

Code:[ZachxPKU/AcceleratedCPlusPlus]

Chapter 6 Using library algorithms

6.1 Analyzing strings

  • generic algorithm 范型算法
  • postfix 后缀 i++
  • prefix 前缀 ++i
  • iterator adaptors 迭代器适配器

6.1.1 Another way to split

这里需要注意为什么要自己写一个space函数取代库函数isspace()。

6.1.2 Palindromes 回文

//  
// Created by Zach on 2022/9/3.  
//  
  
#include <iostream>  
#include <string>  
using namespace std;  
  
bool is_palindromes(const string &s){  
    return equal(s.begin(), s.end(), s.rbegin());  
}  
  
int main(){  
    cout << "Please enter a word: " << endl;  
    string s;  
    cin >> s;  
        if(is_palindromes(s))  
        cout << s << " is a palindrome." << endl;  
    else        cout << s << " is not a palindrome." << endl;  
  
    return 0;  
}

这里要注意,equal在比较两个序列时,默认第二个序列和第一个序列等长。

6.1.3 Finding URLs

//  
// Created by Zach on 2022/9/3.  
//  
  
#include <iostream>  
#include <string>  
#include <vector>  
#include <algorithm>  
#include <cctype>  
  
using namespace std;  
  
bool not_url_char(char c){  
    static const string url_ch = "~;/?:@=&$-_.+!*'(),";  
  
    return !(isalnum(c) || find(url_ch.begin(), url_ch.end(), c) != url_ch.end());  
}  
  
string::const_iterator url_end(string::const_iterator b, string::const_iterator e){  
    return find_if(b, e, not_url_char);  
}  
  
string::const_iterator url_beg(string::const_iterator b, string::const_iterator e){  
    static const string sep = "://";  
  
    typedef string::const_iterator iter;  
  
    iter i = b;  
  
    while((i = search(i,e,sep.begin(), sep.end())) != e) {  
        if(i != b && i + sep.size() != e) {  
            iter beg = i;  
            while(beg != b && isalpha(beg[-1]))  
                --beg;  
            if(beg != i && !not_url_char(i[sep.size()]))  
                return beg;  
        }  
  
        i += sep.size();  
    }  
    return e;  
}  
  
vector<string> find_urls(const string& s){  
    vector<string> ret;  
    typedef string::const_iterator iter;  
    iter b = s.begin(), e = s.end();  
  
    while(b != e){  
        b = url_beg(b,e);  
  
        if(b != e) {  
            iter after = url_end(b,e);  
            ret.push_back(string(b,after));  
            b = after;  
        }  
    }  
    return ret;  
}  
  
int main(){  
    string s;  
    cout << "Please enter a string: " << endl;  
    getline(cin, s);  
  
    vector<string> urls = find_urls(s);  
  
    vector<string>::const_iterator iter = urls.begin();  
  
    if(urls.size() == 0) {  
        cout << "no url in the string!" << endl;  
    }  
  
    while(iter != urls.end()) {  
        cout << *iter << endl;  
        ++iter;  
    }  
  
    return 0;  
}

6.2 Comparing grading schemes

6.2.1 Working with student records

It is a better idea to use this function to check for an empty container than it is to compare the size with 0, because for some kinds of containers, it might be more efficient to check whether the container has any elements than to figure out exactly how many elements there are.

对于一些容器来说,判断其是否为空,比判断其元素个数是否为0要高效。

6.2.2 Analyzing the grades

auxiliary function 辅助函数的用法

void

6.2.3 Grading based on average homework grade

#include <numeric> 数值计算头文件

6.2.4 Median of the completed homework

6.3 Classifying students, revisited

6.3.1 A two-pass solution

6.3.2 A single-pass solution

注意一下 partition 和 stable_partition 的区别,一个会打乱组内顺序,一个不会打乱组内顺序。

6.4 Algorithms, containers, and iterators

Algorithms act on container elements—they do not act on containers.

算法是作用在容器的元素上,而不是作用在容器上。

students.erase(remove_if(students.begin(), students.end(), fgrade),
students.end());

举个例子,这里remove_if是标准库中的算法,它作用在容器的元素上,它不会改变容器的性质,比如大小。而erase是容器的成员函数,它会改变容器的大小。

另外,本节中还特别强调了部分算法和成员函数对迭代器的影响,有时候它们会使迭代器失效,需要重新设置迭代器。

6.5 Details

需要特别注意的是<numeric>里面的accumulate函数的说明。

accumulate(b, e, t)

Creates a local variable and initializes it to a copy of t (with the same type as t, which means that the type of t is crucially important to the behavior of accumulate), adds each element in the range [b, e) to the variable, and returns a copy of the variable as its result. Defined in <numeric>.

函数返回的值由t的类型决定,前面章节也提到0.0和0对结果的影响。

Tips

Tip 6-3

//  
// Created by Zach on 2022/9/4.  
//  
  
#include <iostream>  
#include <vector>  
#include <algorithm>  
  
using namespace std;  
  
int main(){  
    vector<int> u(10, 100);  
  
    vector<int> v;  
  
    copy(u.begin(), u.end(), v.begin());  
  
    vector<int>::const_iterator iter = v.begin();  
  
    cout << v.size();  
  
    while(iter != v.end()){  
        cout << *(iter++) << endl;  
    }  
  
    return 0;  
}

这段代码是会报错的,因为初始化v时,没有给v分配内存空间,v.begin()是一个空指针。

Tip 6-4

上题中的正确代码如下:

//  
// Created by Zach on 2022/9/4.  
//  
  
#include <iostream>  
#include <vector>  
#include <algorithm>  
  
using namespace std;  
  
int main(){  
    vector<int> u(10, 100);  
  
    vector<int> v;  
  
//    copy(u.begin(), u.end(), back_inserter(v));  
  
    copy(u.begin(), u.end(), inserter(v, v.begin()));  
  
    vector<int>::const_iterator iter = v.begin();  
  
    while(iter != v.end()){  
        cout << *(iter++) << endl;  
    }  
  
    return 0;  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值