书籍:C++ Primer Plus (第六版)(中文版)
工具:Dev-C++ 5.11
电脑信息:Intel® Xeon® CPU E5-2603 v3 @ 1.60GHz
系统类型:64位操作系统,基于X64的处理器 windows10 专业版
第16章 string类和标准模板库
16.5 函数对象
实例16.15
functor.cpp
cpp
// functor.cpp using a functor
#include <iostream>
#include <list>
#include <iterator>
#include <algorithm>
template <class T> // functor class defines operator0 ()
class TooBig {
private:
T cutoff;
public:
TooBig(const T & t) : cutoff(t) {}
bool operator()(const T & v) { return v > cutoff; }
};
void outint(int n) { std::cout << n << " "; }
int main()
{
using std::list;
using std::cout;
using std::endl;
TooBig<int> f100(100); // limit = 100
int vals[10] = { 50, 100, 90, 180, 60, 210, 415, 88, 188, 20l };
list<int> yadayada(vals, vals + 10); // range constructor
list<int> etcetera(vals, vals + 10);
// C++11 can use the following instead
//list<int> yadayada = {50, 100, 90, 180, 60, 210, 415, 88, 188, 201} ;
// list<int> etcetera {50, 100, 90, 180, 60, 210, 415, 88, 188, 201};
cout << "Original lists:\n";
for_each(yadayada.begin(), yadayada.end(), outint);
cout << endl;
for_each(etcetera.begin(), etcetera.end(), outint);
cout << endl;
yadayada.remove_if(f100); // use a named function object
etcetera.remove_if(TooBig<int> (200)); // construct a function object
cout << "Trimmed lists:\n";
for_each(yadayada.begin(), yadayada.end(), outint); cout << endl;
for_each(etcetera.begin(), etcetera.end(), outint);
cout << endl;
return 0;
}
编译运行结果:
cpp
Original lists:
50 100 90 180 60 210 415 88 188 20
50 100 90 180 60 210 415 88 188 20
Trimmed lists:
50 100 90 60 88 20
50 100 90 180 60 88 188 20
--------------------------------
Process exited after 0.3615 seconds with return value 0
请按任意键继续. . .
实例16.16
funadap.cpp
cpp
// funadap.cpp -- using function adapters
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <functional>
void Show(double);
const int LIM = 6;
int main()
{
using namespace std;
double arr1[LIM] = {28, 29, 30, 35, 38, 59};
double arr2[LIM] = {63, 65, 69, 75, 80, 99};
vector<double> gr8(arr1, arr1 + LIM);
vector<double> m8(arr2, arr2 + LIM);
cout.setf(ios_base::fixed);
cout.precision(1);
cout << "gr8:\t";
for_each(gr8.begin(), gr8.end(), Show);
cout << endl;
cout << "m8: \t";
for_each(m8.begin(), m8.end(), Show);
cout << endl;
vector<double> sum(LIM);
transform(gr8.begin(), gr8.end(), m8.begin(), sum.begin(), plus<double>());
cout << "sum:\t";
for_each(sum.begin(), sum.end(), Show);
cout << endl;
vector<double> prod(LIM);
transform(gr8.begin(), gr8.end(), prod.begin(), bind1st(multiplies<double>(), 2.5));
cout << "prod:\t";
for_each(prod.begin(), prod.end(), Show);
cout << endl;
return 0;
}
void Show(double v)
{
std::cout.width(6);
std::cout << v << ' ';
}
编译运算结果:
cpp
gr8: 28.0 29.0 30.0 35.0 38.0 59.0
m8: 63.0 65.0 69.0 75.0 80.0 99.0
sum: 91.0 94.0 99.0 110.0 118.0 158.0
prod: 70.0 72.5 75.0 87.5 95.0 147.5
--------------------------------
Process exited after 0.382 seconds with return value 0
请按任意键继续. . .
16.6 算法
实例16.17
strgst1.cpp
cpp
// strgstl.cpp -- applying the STL to a string
#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;
}
编译运算结果:
cpp
Enter the letter grouping (quit to quit): awl
Permutations of awl
alw
awl
law
lwa
wal
wla
Enter next sequence (quit to quit): all
Permutations of all
all
lal
lla
Enter next sequence (quit to quit): quit
Done.
--------------------------------
Process exited after 23.19 seconds with return value 0
请按任意键继续. . .
实例16.18
listrmv.cpp
cpp
// listrmv.cpp -- applying the STL to a string
#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;
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;
last = remove(lb.begin(), lb.end(), 4);
cout << "After using the remove() functionin";
cout << "lb:\t";
for_each(lb.begin(), lb.end(), Show); cout << endl;
lb.erase(last, lb.end());
cout << "After using the erase!) method:\n"; cout << "lbAt";
for_each(lb.begin(), lb.end(), Show); cout << endl;
return 0;
}
void Show(int v)
{
std::cout << v << ' ';
}
编译运算结果:
cpp
Original list contents:
4 5 4 2 2 3 4 8 1 4
After using the remove() method:
la: 5 2 2 3 8 1
After using the remove() functioninlb: 5 2 2 3 8 1 4 8 1 4
After using the erase!) method:
lbAt5 2 2 3 8 1
--------------------------------
Process exited after 0.157 seconds with return value 0
请按任意键继续. . .
实例16.19
usealgo.cpp
cpp
//usealgo.cpp -- using several STL elements
#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;
// place words in set, converting to lowercase
set<string> wordset;
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;
// place word and frequency in map
map<string, int> wordmap;
set<string>::iterator si;
for (si = wordset.begin(); si != wordset.end(); si++)
wordmap[*si] = count(words.begin(), words.end(), *si);
// display map contents
cout << "\nWord frequency:\n";
for (si = wordset.begin();
si != wordset.end(); si++) cout << *si << ":" << wordmap[*si] << endl;
return 0;
}
string & ToLower(string & st)
{
transform(st.begin(), st.end(), st.begin(), toLower);
return st;
}
void display(const string & s)
{
cout << s << " ";
}
编译运算结果:
cpp
Enter words (enter quit to quit):
The dog saw the cat and thought the cat fat
The cat thought the cat perfect
quit
You entered the following words:
The dog saw the cat and thought the cat fat The cat thought the cat perfect
Alphabetic list of words:
and cat dog fat perfect saw the thought
Word frequency:
and:1
cat:4
dog:1
fat:1
perfect:1
saw:1
the:5
thought:2
--------------------------------
Process exited after 60.23 seconds with return value 0
请按任意键继续. . .
16.7 其它库
实例16.20
valvect.cpp
cpp
// valvect.cpp -- comparing vector and valarray
#include <iostream>
#include <valarray>
#include <vector>
#include <algorithm>
int main()
{
using namespace std;
vector<double> data;
double temp;
cout << "Enter numbers (<=0 to quit):\n";
while (cin >> temp && temp > 0)
data.push_back(temp);
sort(data.begin(), data.end());
int size = data.size();
valarray<double> numbers(size);
int i;
for (i = 0; i < size; i++)
numbers[i] = data[i];
valarray<double> sq_rts(size);
sq_rts = sqrt(numbers);
valarray<double> results(size);
results = numbers + 2.0 * sq_rts;
cout.setf(ios_base::fixed);
cout.precision(4);
for (i = 0; i < size; i++)
{
cout.width(8);
cout << numbers[i] << ': ';
cout.width(8);
cout << results[i] << endl;
}
cout << "done\n";
return 0;
}
编译运算结果:
cpp
Enter numbers (<=0 to quit):
3.3 1.8 5.2 10 14.4 21.6 26.9 0
1.800014880 4.4833
3.300014880 6.9332
5.200014880 9.7607
10.000014880 16.3246
14.400014880 21.9895
21.600014880 30.8952
26.900014880 37.2730
done
--------------------------------
Process exited after 22.42 seconds with return value 0
请按任意键继续. . .
实例16.21
vslice.cpp
cpp
//vslice.cpp -- using valarray slices
#include <iostream>
#include <valarray>
#include <cstdlib>
const int SIZE = 12;
typedef std::valarray<int> vint; // simplify declarations
void show(const vint & v, int cols);
int main()
{
using std::slice; // from <valarray>
using std::cout;
vint valint(SIZE); // think of as 4 rows of 3
int i;
for (i = 0; i < SIZE; ++i)
valint[i] = std::rand() % 10;
cout << "Original array:\n";
show(valint, 3); // show in 3 columns
vint vcol(valint[slice(1, 4, 3)]); // extract 2nd column
cout << "Second column:\n";
show(vcol, 1);// show in 1 column
vint vrow(valint[slice(3, 3, 1)]);// extract 2nd row
cout << "Second row:\n";
show(vrow, 3);
valint[slice(2, 4, 3)] = 10;// assign to 2nd column
cout << "Set last column to 10:\n"; show(valint, 3);
cout << "Set first column to sum of next two:\n";
// + not defined for slices, so convert to valarray<int>
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;
}
编译运行结果:
cpp
Original array:
1 7 4
0 9 4
8 8 2
4 5 5
Second column:
7
9
8
5
Second row:
0 9 4
Set last column to 10:
1 7 10
0 9 10
8 8 10
4 5 10
Set first column to sum of next two:
17 7 10
19 9 10
18 8 10
15 5 10
--------------------------------
Process exited after 0.4513 seconds with return value 0
请按任意键继续. . .
实例16.22
ilist.cpp
cpp
// ilist.cpp -- use initializer_list (C++11 feature)
#include <iostream>
#include <initializer_list>
double sum(std::initializer_list<double> il);
double average(const std::initializer_list<double> & ril);
int main()
{
using std::cout;
cout << "List l: sum = " << sum({ 2,3,4 }) << ", ave = " << average({ 2,3,4 }) << '\n';
std::initializer_list<double> dl = { 1.1, 2.2, 3.3, 4.4, 5.5 };
cout << "List 2: sum = " << sum(dl) << ", ave = " << average(dl)<< '\n';
dl = { 16.0, 25.0, 36.0, 40.0, 64.0 };
cout << "List 3: sum = " << sum(dl) << ", ave = " << average(dl) << '\n';
return 0;
}
double sum(std::initializer_list<double> il)
{
double tot = 0;
for (auto p = il.begin(); p != il.end(); p++)
tot += *p;
return tot;
}
double average(const std::initializer_list < double> & ril)
{
double tot = 0;
int n = ril.size();
double ave = 0.0;
if (n > 0)
{
for (auto p = ril.begin(); p != ril.end(); p++)
tot += *p;
ave = tot / n;
}
return ave;
}
编译运算结果:
cpp
List l: sum = 9, ave = 3
List 2: sum = 16.5, ave = 3.3
List 3: sum = 181, ave = 36.2
--------------------------------
Process exited after 0.3508 seconds with return value 0
请按任意键继续. . .