美文网首页
Coursera C++ Part A [Week4] STL

Coursera C++ Part A [Week4] STL

作者: 小啾Kris | 来源:发表于2019-09-30 21:56 被阅读0次

这节课掌握重要情报,教授家里养了Googly和Hamster两只猫,名字取得好恶趣味233

Course Overview

  • Enum and enum class
  • Prim's and Kruskal's algorithms
  • 重载and友元函数
  • STL and STL in C++11
  • 输出随机图

Suggested Readings

  • C++ for C Programmers, ch. 8
  • C++ by Dissection, ch. 6-7

1. enum and enum class

enum中变量是可以进行比较的,但是在enum type中, 变量在类型上已经有了区别,所以不能进行比较。在有了类型区别以后,代码安全性就有所提升不会不小心触发类型转换引起麻烦

enum Color{RED, BLUE, WHITE} //颜色类
enum Traffic{RED, Yellow, GREEN} //交通灯
// 这种情况下 Color::RED == Traffic::RED
enum class Color{RED, BLUE, WHITE} //颜色类
enum class Traffic{RED, Yellow, GREEN} //交通灯
// 使用enum class时 Color::RED != Traffic::RED

2. MST最小生成树

生成树:图中的边的集合,构成一棵树,这些边连起了图中所有的定点,并且树中不能有环。对于一个有N个节点的图,生成树有N-1个边。
Prim算法:
从单个顶点开始,将距离闭集中所有节点最近的一个节点放入闭集中,并记录它和闭集的最短距离,一次一个节点,将节点连接到现有树。
Prim算法属于贪心算法,贪心算法秉持了在局部挑选最优的概念。
Kruskal's算法:
Kruskal算法从边出发,从最小边出发,用贪心算法取下一个最小权重的边加入到已得到的联通分量里,如果成环则不加入。

3.重载and友元函数

访问类的私有成员有两种方式:通过类的成员函数和通过友元函数。成员函数的第一个参数默认为类的对象,在第一个参数非此类对象的时候就很不方便,例如冲裁ostream <<的时候,此时就需要通过友元的方式在类体外定义友元函数

class point{
  friend ostream& operator<<(ostream& out, point p);
  private:
      int x, y;
};
ostream& operator<<(ostream& out, const point& p){
    out << "("<<p.x<<", "<<p.y<<")";
    return out;
} //不加friend报错

4.STL and STL in C++11

  • STL
    STL容器是由container, algorithm, iterator组成的
    container包括vector, list, map
    iterator包括forward, backward, random
    algorithms包括sort, permute
// vector example
#include <vector>
using namesapce std;
vector<int> v(10)
for (vector<int>::iterator p = v.begin(); p != v.end(); ++p) // vector遍历
    cout << *p <<'\t'
  • auto
    在使用中 vector<int>::iterator 这样的表达是十分麻烦且容易出错的,C++11中启用了一个新功能auto。auto意味着推断类型,因此被auto标注的类型必须是可以推断的,如果auto不能理解该类型,auto就无法工作。上面的例子可以写成
for (vector<int>::iterator p = v.begin(); ...) //原始写法
for (auto p = v.begin(); ...)// 用auto修饰的写法,编译器知道该表达式的类型为一个vector迭代器

// 其他例子
auto i = 3; // i是int类型
auto d = 3.7; // d是double类型
auto c = d; // c是double类型
  • vector methods
#include <vector>
using namesapce std;
vector<int> v;
v.size();  // vector的长度
v.resize(int size); // resize the vector

// Constructors
vector<T> v; // empty vector
vector<T> v(n); // size n with default constructor T() called for each element
vector<T> v(n, value); value is of type T (or convertible to T)
  • fstream: use with a file
  • C++11的循环功能
#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>

ifstream data_file("data.txt"); // text file containing data
istream_iterator<int> start(data_file), end;
vector<int> data(start, end); // start与end之间所有的数据都会保存在data里面
for(double d: data) // C++11 for 新用法
     sum += d;
for(auto& element: data) // auto infers type
     element = element + 2; // allows mutate

// another example
ifstream word_file("word.txt");
istream_iterator<string> start(word_file), end;
vector<string> words(start, end) // vector会自动用空格作为分割
// print the vectore
for(auto str: words)
   cout << str <<'\t';
sort(words.begin(), words.end()); // sort the vector
  • iterators category
  1. input(weakest), 只允许读入数据,每条数据只能看一遍。必须实现++, dereferencing operator *, ==, !=
// use an input iterator
#include<istream>
#include<fstream>
#include<numeric>
using namespace std;
s
int main(){
  ifstream myin('data')
  istream_iterator<int> in(myin); //begin of the file
  istream_iterator<int> eos; //end of stream
  cout<<"sum of data is"<<accumulate(in, eos, 0)<<endl;//accumulate在numeric库中,从0开始累计
}
  1. output, 输出迭代器,每条数据只能写一遍
  2. forward, 可读可写,可以被重复使用,每边只能是单向的
  3. bidirectional, 允许多遍使用,双向
  4. random access(strongest), 随机访问,复杂度为O(1)
    STL的原则是,使用最弱的迭代器实现最高校的算法

5.输出随机图

最后使用本节课的内容完成随机图的生成和输出

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <fstream>
using namesapce std;

double prob()
{
    return (static_cast<double> (rand())/RAND_MAX)
// rand()和RAND_MAX都是整数,rand() 输出一个小于RAND_MAX的正整数,如果不转换成double类型相除就会等于0,转换成double得到介于0,1之间的值
}
int main(){
    int size = 15; 
    double density; //get from user
    cout <<"graph size?"<<endl;
    cin >> size;
    cout<< "graph density(0,1)?"<<endl;
    cin >> density;
// creat matrices off heap
    bool** graph; // present a graph in a bool matrix
    int ** color;
    int** cost;
    srand(time(0)) // seed random number generator
    graph = new bool*[size];
    color = new int*[size];
    cost = new int*[size];
    for (int i=0;i<size;++i){
        graph[i] = new bool[size];
        color[i] = new int[size];
        cost[i] = new int[size];
    }
// generate graph
    for(int i=0;i<size;++i) //generate undirected edges
        for(int j=i; j<size;++j)
              if(i==j) graph[i][j]=false; //no loops
              else graph[i][j] = graph[j][i] = (prob()<density)
    for(int i=0;i<size;++i) //generate cost and color
        for(int j=i;j<size;++j)
             if (graph[i][j]){
                    color[i][j] = color[j][i] = rand()%3; //3种颜色
                    cost[i][j] = cost[j][i] = prob()*30; //成本的范围0-30
             }
    ofstream outp("graph_data.txt");
    outp <<size<<"\n";
    for(int i=0;i<size; ++i)
        for(int j=0;j<size;++j){
            if(graph[i][j])
                outp << i <<'\t' <<j<<'\t'<<
                        cost[i][j]<<'\t'<<color[i][j]<<'\t'
        }
}

C++ Part A完结

自此C++ Part完结撒花🎉
更多C++功能如lambda将在Part B中继续介绍

相关文章

网友评论

      本文标题:Coursera C++ Part A [Week4] STL

      本文链接:https://www.haomeiwen.com/subject/nmctyctx.html