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

总体设计

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

使用模板来提供泛型

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

STL算法分组:

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

<algorithm>

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

<algorithm>

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

<algorithm>

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

<numeric>

算法有两个版本

就地版和复制版

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

就地版不用

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

示例

#include <iostream>
#include <string>
#include <algorithm>

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 <<letters << endl;
    cout << "Enter next sequence(quit to quit): ";
  }
  cout << "Done.\n";
  return 0;
}

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

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

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

程序示例

#include <iostream>
#include <list>
#include <algorithm>
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<int> la(ar, ar + LIM);
  list<int> 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<int>::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 << ' ';
}

运行结果

程序示例

#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <iterator>
#include <algorithm>
#include <cctype>
using namespace std;

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

int main()
{
  vector<string> 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<string> wordset;
// set容器 自动排序去重
  transform(words.begin(), words.end(), insert_iterator<set<string>> (wordset, wordset.begin()), ToLower);
  cout << "\nAlphabetic list of words:\n";
  for_each(wordset.begin(), wordset.end(), display);
  cout << endl;

  map<string, int> wordmap;
  set<string>::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 << " ";
}

程序结果

其他库

comlex为复数使用的类模板

random提供随机数模板

vector valarray array容器的不同作用

slice类 可以用作数组索引

#include <iostream>
#include <valarray>
#include <cstdlib>

const int SIZE = 12;
typedef std::valarray<int> 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;
}

程序结果

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

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

总结:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@凌晨三点半

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值