Coursera C++ Part B [Week1] C++进

2019-09-30  本文已影响0人  小啾Kris

C++ Part B是C++进阶课程,bf
课程网址 https://www.coursera.org/learn/c-plus-plus-b/home/welcome

course overview

参考书

1. More Standard Template Library

2. New features of C++, such us semantics and lambda expressions

enum color{RED, BLUE};
enum spotlight{RED, GREEN};
// 如果在一个scope下会导致编译器错误

enum class会自动定义成int,但是也可以特化为别的类

enum class Color: short{RED,BLUE,GREEN};
// 一段实现序列平方的例子
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
using namespace std;

template<typename FowardIterator>
void square(FowardIterator first, FowardIterator last){
    for(; first!=last;first++)
        *first = (*first)*(*first);
}
int main(){
    ...... //省略 w could be anything like a vector<int>
    square(w.begin(), w.end());
    for (auto i:w) //range for
        cout << i <<'\t'
    cout<<endl;
}

3. Iterator categories and examples

1). 单项指针
用C++计算扑克牌同花顺的概率

// 定义花色类和数字类来表示扑克牌
enum class suit:short{SPADE, HEART, DIAMOND, CLUB} //用short相比int和float更加节省内存

class pips{
public:
    pips(int val):v(val){assert(v>0 && v<14);}
    friend ostream& operator<<(ostream& out, const pips& p);
    int get_pips(){return v;}
private:
    int v;
}

//用suit 和 pips表示扑克牌
class card{
public:
    card():s(suit:SPADE),v(1){}
    card(suit s, pips v):s(s),v(v){}
    friend ostream& operator<<(ostream& out, const card& c);
    suit get_suit(){return s;}
    pips get_pips(return v;}
private:
    suit s;
    pips v;
}
ostream& operator<<(ostream& out, const card& c){
    cout<<c.v<<c.s;
    return out; 
}

//建立card向量
void int_deck(vector<card>& d){
    for (int i=1;i<14;++i){
        card c(suit:: SPADE, i);
         d[i-1] = c;
    }
    for (int i=1;i<14;++i){
        card c(suit::HEART, i);
        d[i+12] = c;
    }
    for (int i=1; i<14;++i){
        card c(suit::DIAMOND, i);
        c[i+25] = c
    }
    for (int i=1; i<14;++i){
        card c(suit::CLUB, i);
        c[i+38] = c
    }
}

void print(vector <card>& deck){
    for(auto p=deck.begin();p!=deck.end();++p)
        cout<<*p;
    cout<<endl;
}
//print 的另一种写法
void print(vector<card>& deck){
    for(auto cardval:deck)
        cout<<cardval;
    cout<<endl;
}
//判断是否是同花
bool is_flush(vector <card> & hand){
    suit s = hand[0].get_suit();
    for(auto p= hand.begin()+1; p!=hand.end();++p)
        if(s!=p->get_suit())
            return false;
     return true;
}
//判断是否连顺
bool is_straight(vector<card>& hand){
    int pips_v[5], i=0
    for(auto p=hand.begin();p!=hand.end();++p)
        pips_v[i++] = (p->get_pips()).get_pips();
    sort(pips_v, pips_v+5);  // stl iterator range
    if (pips_v[0]!=1) //没有A
        return(pips_v[0]==pips_v[1]-1&&
                   pips_v[1]==pips_v[2]-1&&
                   pips_v[2]==pips_v[3]-1&&
                   pips_v[3]==pips_v[4]-1);
    else //有A
        return(pips_v[0]==pips_v[1]-1&&
                   pips_v[1]==pips_v[2]-1&&
                   pips_v[2]==pips_v[3]-1&&
                   pips_v[3]==pips_v[4]-1)||
                   pips_v[1]==10&&pips_v[2]==11&&
                   pips_v[3]==12&&pips_v[4]==13;
}
bool is_straight_flush(vector<card> & hand){
    return is_flush(hand)&&is_straight(hand);
}
// set up simulation
int main(){
    vector<card> deck(52);
    srand(time(0));
    init_deck(deck);
    int how_many; 
    int flush_count=0; 
    int str_count = 0;
    int str_flush_count = 0;
    cout<<'How many shuffles?';
    cin>>how_many;
    for(int loop=0;loop<how_many;++loop){
        random_shuffle(deck.begin(), deck.end()); //stl algorithm
        vector<card> hand(5);
        int i = 0;
        for (auto p = deck.begin();i<5;++p)
            hand[i++] =  *p;
        if (is_flush(hand))
            flush_count++;
         if(is_straight(hand))
             str_count++;
         if(is_straight_flush(hand))
             int str_flush_count++;
    }
    cout <<'Flushes'<<flush_count<<'out of'<<how_many<<endl;
    cout <<'Straights'<<str_count<<'out of'<<how_many<<endl;
    cout <<'Straight Flushes'<<str_flush_count<<'out of'<<how_many<<endl;
}

2)双向指针BidirectionalIterator
双向指针支持双向移动,既有++又有--运算。
STL库中一个用双向指针实现的经典的算法就是reverse()

template<typename T>
void reverse(BidirctionalIterator first, BidirctionalIterator last);

//用双向指针检查是否是回文序列
template<typename Bidirectional>
bool isPalindrome(Bidirectional first, Bidirectional last){
    while(true){
        lass--;
        if(first==last)//assume >= undefined
            break;
        if(*first != *last)
            return false;
        first++;
        if(first == last)
            break;
    }
    return true;
}

3)随机指针 Random access iterator

template<class RandomAccessIterator>
void sort(RandomAccessIterator first, RandomAccessIterator last);

用随机指针实现随机选出元素

#include<csddef> //ptrdiff_t 是signed integral type
template<typename RandomAccess>
RandomAccess pickRandEI(RandomAccess first, RandomAccess last){
    ptrdiff_t temp = last-first;
    return first+rand()%temp;
}

4.容器和算法

template<class InputIter, Class T>
InputIter find(InputIter  b, InputIter e, const T& t); // 搜索t

在STL中经常可以看到算法的另一种表示

template<class InputIter, Class Predicte>
InputIter find_if(InputIter  b, InputIter e, Predicte p);

在这个版本中,我们搜索谓词而不是值,这样的形式增加了函数的功能
另一个非变异算法还有的还有

template<class InputIter, Class Function>
InputIter for_each(InputIter  b, InputIter e, Function f);// apply f for value in range b to e

5. Lambda表达式

C++11有个新功能lambda,类似未命名的函数

[capture list](params list) mutable exception->return type{function body}
// capture list: 捕获外部变量列表
// params list: 形参列表
// mutable指示符:  说明是否可以修改捕获的外部变量
// exception: 异常设定
// return type: 返回类型,可以不声明
//Unnamed function
[](int i){cout<<i<<endl;}// 不需要声明返回值类型,编译器会自动识别返回值
[](int n)->int{return ++n;} // explicit,声明了返回值类型为int
上一篇下一篇

猜你喜欢

热点阅读