C++ Primer Plus 学习笔记 第十六章 算法 其他库

总体设计

通过迭代器来标识要处理的数据区间和结果放置位置,有些算法函数接收参数

使用模板来提供泛型

使用迭代器来访问容器中的通用表示

STL算法分组:

非修改式序列操作:操作容器元素但不修改:find(),for_each()等

修改式序列操作:可以修改容器内容或排列顺序transform(), random_shuffle() copy()等

排序和相关操作:集合操作。

通用数字运算:计算内部乘积,计算相邻差等函数 

算法有两个版本

就地版和复制版

复制版的算法函数名要加_copy结尾

就地版不用

_if版本:根据函数应用于容器元素得到的结果来决定是否将容器中的值直接替换

C++ Primer Plus 学习笔记 第十六章 算法 其他库_第1张图片

示例

#include 
#include 
#include 

int main()
{
  using namespace std;
  string letters;
  cout << "Enter the letter grouping (quit to quit): ";
  while(cin >> letters && letters != "quit")
  {
    cout << "Permutations of " << letters << endl;
    sort(letters.begin(), letters.end());
    cout << letters << endl;
// 全排序 吧容器的所有元素可能产生的排序组合(唯一的)全部迭代出来
    while(next_permutation(letters.begin(), letters.end()))
      cout <

C++ Primer Plus 学习笔记 第十六章 算法 其他库_第2张图片

有时候 使用某个容器自由的成员函数来处理一些算法是更好地选择

比如list容器  自带remove() 再删除了特定的元素后会自动调整容器长度(list是链表类型的数据结构)

而非成员函数 remove()只能删除元素,无法自动调整容器长度

程序示例

#include 
#include 
#include 
void Show(int);
const int LIM = 10;
int main()
{
  using namespace std;
  int ar[LIM] = {4, 5, 4, 2, 2, 3, 4, 8, 1, 4};
  list la(ar, ar + LIM);
  list lb(la);
  cout << "Original list contents:\n\t";
  for_each(la.begin(), la.end(), Show);
  cout << endl;
// 使用了list的成员函数 删除值为4的元素
  la.remove(4);
  cout << "After using the remove() method:\n";
  cout << "la:\t";
  for_each(la.begin(), la.end(), Show);
  cout << endl;
  list::iterator last;
// 非成员函数remove() 在删除完相应的元素之后 会将未删除的元素相应的写到list对象的开头位置
// 替换掉原来的值
// 然后返回一个指向新的超尾值的迭代器
  last = remove(lb.begin(), lb.end(), 4);
  cout << "After using the remove(0 function:\n";
  cout << "lb:\t";
  for_each(lb.begin(), lb.end(), Show);
  cout << endl;
// 删除从last开始到原list迭代器尾部的这部分元素。因为后面那几个元素已经没有存在的意义了
  lb.erase(last, lb.end());
  cout << "After using the erase(0 method:\n";
  cout << "lb:\t";
  for_each(lb.begin(), lb.end(), Show);
  cout << endl;
      
  return 0;
}

void Show(int v)
{
  std::cout << v << ' ';
}

运行结果

C++ Primer Plus 学习笔记 第十六章 算法 其他库_第3张图片

程序示例

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

char toLower(char ch) {return tolower(ch);}
string & ToLower(string & st);
void display(const string & s);

int main()
{
  vector words;
  cout << "Enter words (enter quit to quit):\n";
  string input;
  while(cin >> input && input != "quit")
    words.push_back(input);

  cout << "You entered the following words:\n";
  for_each(words.begin(), words.end(), display);
  cout << endl;

  set wordset;
// set容器 自动排序去重
  transform(words.begin(), words.end(), insert_iterator> (wordset, wordset.begin()), ToLower);
  cout << "\nAlphabetic list of words:\n";
  for_each(wordset.begin(), wordset.end(), display);
  cout << endl;

  map wordmap;
  set::iterator si;
// 计算各个单词出现的次数
  for(si = wordset.begin(); si != wordset.end(); si++)
    wordmap[*si] = count(words.begin(), words.end(), *si);
  cout << "\nWord frequency:\n";
  for (si = wordset.begin(); si != wordset.end(); si++)
    cout << *si << ": " << wordmap[*si] << endl;

  return 0;
}
// 大写string转换成小写string(迭代每个字符)
string & ToLower(string & st)
{
  transform(st.begin(), st.end(), st.begin(), toLower);
  return st;
}

void display(const string & s)
{
  cout << s << " ";
}

程序结果

C++ Primer Plus 学习笔记 第十六章 算法 其他库_第4张图片

其他库

comlex为复数使用的类模板

random提供随机数模板

vector valarray array容器的不同作用

C++ Primer Plus 学习笔记 第十六章 算法 其他库_第5张图片

slice类 可以用作数组索引

#include 
#include 
#include 

const int SIZE = 12;
typedef std::valarray vint;
void show(const vint & v, int cols);
int main()
{
  using std::cout;
  using std::slice;
  vint valint(SIZE);

  int i;
  for (i = 0; i < SIZE; ++i)
    valint[i] = std::rand() % 10;
  cout << "Original array:\n";
  show(valint, 3);
// slice格式: 起始下标, 数量, 跨距
  vint vcol(valint[slice(1, 4, 3)]);
  cout << "Second column:\n";
  show(vcol, 1);
  vint vrow(valint[slice(3, 3, 1)]);
  cout << "Second row:\n";
  show(vrow,3);
  valint[slice(2, 4, 3)] = 10;
  cout << "Set last column to 10:\n";
  show(valint, 3);
  cout << "Set first column to sum of next tow:\n";
  valint[slice(0, 4, 3)] = vint(valint[slice(1, 4, 3)])
                           + vint(valint[slice(2, 4, 3)]);
  show(valint, 3);
  return 0;
}

void show(const vint & v, int cols)
{
  using std::cout;
  using std::endl;

  int lim = v.size();
  for (int i = 0; i < lim; ++i)
  {
    cout.width(3);
    cout << v[i];
    if (i % cols == cols - 1)
      cout << endl;
    else
      cout << ' ';
  }
  if (lim % cols != 0)
    cout << endl;
}

程序结果

C++ Primer Plus 学习笔记 第十六章 算法 其他库_第6张图片

initializer_list 将STL容器初始化为一些列值:

std::vector payments {45.99, 39.23, 19.95, 89.01};

总结:

C++ Primer Plus 学习笔记 第十六章 算法 其他库_第7张图片

C++ Primer Plus 学习笔记 第十六章 算法 其他库_第8张图片

第十六章完结 卧槽终于完结了

你可能感兴趣的:(C++,C++,Primer,Plus)