使用partition()
在函数调用后
每个结果子序列的元素顺序并没有被指定
但是用stable_partition()
序列运算的演示
原来的代码有错 这是第2版 书已经到第5版了
看了 https://blog.csdn.net/felomeng/article/details/4132492
就加了个#include<functional> 尝试一下可以运行
我这里加上去了
要不然 出现
error C2065: “greater”: 未声明的标识符
error C3861: “bind2nd”: 找不到标识符
greater是采用模板生成函数
//: C06:Manipulations.cpp
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// Shows basic manipulations.
//{L} Generators
// NString
#include <vector>
#include <string>
#include <algorithm>
#include "PrintSequence.h"
#include "NString.h"
#include "Generators.h"
#include <functional>
using namespace std;
int main() {
vector<int> v1(10);
// Simple counting:
generate(v1.begin(), v1.end(), SkipGen());
print(v1.begin(), v1.end(), "v1", " ");
vector<int> v2(v1.size());
copy_backward(v1.begin(), v1.end(), v2.end());
print(v2.begin(), v2.end(), "copy_backward", " ");
reverse_copy(v1.begin(), v1.end(), v2.begin());
print(v2.begin(), v2.end(), "reverse_copy", " ");
reverse(v1.begin(), v1.end());
print(v1.begin(), v1.end(), "reverse", " ");
int half = v1.size() / 2;
// Ranges must be exactly the same size:
swap_ranges(v1.begin(), v1.begin() + half,
v1.begin() + half);
print(v1.begin(), v1.end(), "swap_ranges", " ");
// Start with a fresh sequence:
generate(v1.begin(), v1.end(), SkipGen());
print(v1.begin(), v1.end(), "v1", " ");
int third = v1.size() / 3;
for(int i = 0; i < 10; i++) {
rotate(v1.begin(), v1.begin() + third, v1.end());
print(v1.begin(), v1.end(), "rotate", " ");
}
cout << "Second rotate example:" << endl;
char c[] = "aabbccddeeffgghhiijj";
const char CSZ = strlen(c);
for(int i = 0; i < 10; i++) {
rotate(c, c + 2, c + CSZ);
print(c, c + CSZ, "", "");
}
cout << "All n! permutations of abcd:" << endl;
int nf = 4 * 3 * 2 * 1;
char p[] = "abcd";
for(int i = 0; i < nf; i++) {
next_permutation(p, p + 4);
print(p, p + 4, "", "");
}
cout << "Using prev_permutation:" << endl;
for(int i = 0; i < nf; i++) {
prev_permutation(p, p + 4);
print(p, p + 4, "", "");
}
cout << "random_shuffling a word:" << endl;
string s("hello");
cout << s << endl;
for(int i = 0; i < 5; i++) {
random_shuffle(s.begin(), s.end());
cout << s << endl;
}
NString sa[] = { "a", "b", "c", "d", "a", "b",
"c", "d", "a", "b", "c", "d", "a", "b", "c"};
const int SASZ = sizeof sa / sizeof *sa;
vector<NString> ns(sa, sa + SASZ);
print(ns.begin(), ns.end(), "ns", " ");
vector<NString>::iterator it =
partition(ns.begin(), ns.end(),
bind2nd(greater<NString>(), "b"));
cout << "Partition point: " << *it << endl;
print(ns.begin(), ns.end(), "", " ");
// Reload vector:
copy(sa, sa + SASZ, ns.begin());
it = stable_partition(ns.begin(), ns.end(),
bind2nd(greater<NString>(), "b"));
cout << "Stable partition" << endl;
cout << "Partition point: " << *it << endl;
print(ns.begin(), ns.end(), "", " ");
getchar();
} ///:~
输出
v1: 0 1 2 3 4 5 6 7 8 9
copy_backward: 0 1 2 3 4 5 6 7 8 9
reverse_copy: 9 8 7 6 5 4 3 2 1 0
reverse: 9 8 7 6 5 4 3 2 1 0
swap_ranges: 4 3 2 1 0 9 8 7 6 5
v1: 0 1 2 3 4 5 6 7 8 9
rotate: 3 4 5 6 7 8 9 0 1 2
rotate: 6 7 8 9 0 1 2 3 4 5
rotate: 9 0 1 2 3 4 5 6 7 8
rotate: 2 3 4 5 6 7 8 9 0 1
rotate: 5 6 7 8 9 0 1 2 3 4
rotate: 8 9 0 1 2 3 4 5 6 7
rotate: 1 2 3 4 5 6 7 8 9 0
rotate: 4 5 6 7 8 9 0 1 2 3
rotate: 7 8 9 0 1 2 3 4 5 6
rotate: 0 1 2 3 4 5 6 7 8 9
Second rotate example:
bbccddeeffgghhiijjaa
ccddeeffgghhiijjaabb
ddeeffgghhiijjaabbcc
eeffgghhiijjaabbccdd
ffgghhiijjaabbccddee
gghhiijjaabbccddeeff
hhiijjaabbccddeeffgg
iijjaabbccddeeffgghh
jjaabbccddeeffgghhii
aabbccddeeffgghhiijj
All n! permutations of abcd:
abdc
acbd
acdb
adbc
adcb
bacd
badc
bcad
bcda
bdac
bdca
cabd
cadb
cbad
cbda
cdab
cdba
dabc
dacb
dbac
dbca
dcab
dcba
abcd
Using prev_permutation:
dcba
dcab
dbca
dbac
dacb
dabc
cdba
cdab
cbda
cbad
cadb
cabd
bdca
bdac
bcda
bcad
badc
bacd
adcb
adbc
acdb
acbd
abdc
abcd
random_shuffling a word:
hello
oellh
ollhe
ehlol
lleho
loehl
ns: a [0] b [0] c [0] d [0] a [1] b [1] c [1] d [1] a [0] b [0] c [0] d [0] a [1] b [1] c [1]
Partition point: b [1]
c [1] d [0] c [0] d [0] c [0] d [1] c [1] b [1] a [0] b [0] a [1] b [0] a [1] b [1] a [0]
Stable partition
Partition point: a [0]
c [0] d [0] c [1] d [1] c [0] d [0] c [1] a [0] b [0] a [1] b [1] a [0] b [0] a [1] b [1]
vector<int>v1初始化为一个简单的升序序列
并且打印这个序列
reverse_copy()实际上创建一个相反顺序的复制
reverse()在适当的位置执行颠倒操作
rotate()是重新创建一个升序序列
通过多次交换v1的三分之一来完成排序工作
第2个rotate()使用了字符且每次仅交换两个字符
贴剩下的代码
//: C06:Generators.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// Different ways to fill sequences.
#ifndef GENERATORS_H
#define GENERATORS_H
#include <cstring>
#include <set>
#include <cstdlib>
// A generator that can skip over numbers:
class SkipGen {
int i;
int skp;
public:
SkipGen(int start = 0, int skip = 1)
: i(start), skp(skip) {}
int operator()() {
int r = i;
i += skp;
return r;
}
};
// Generate unique random numbers from 0 to mod:
class URandGen {
std::set<int> used;
int limit;
public:
URandGen(int lim) : limit(lim) {}
int operator()() {
while(true) {
int i = int(std::rand()) % limit;
if(used.find(i) == used.end()) {
used.insert(i);
return i;
}
}
}
};
// Produces random characters:
class CharGen {
static const char* source;
static const int len;
public:
char operator()() {
return source[std::rand() % len];
}
};
#endif // GENERATORS_H ///:~
//: C06:Generators.cpp {O}
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
#include "Generators.h"
const char* CharGen::source = "ABCDEFGHIJK"
"LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const int CharGen::len = std::strlen(source);
///:~
//: C06:NString.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// A "numbered string" that keeps track of the
// number of occurrences of the word it contains.
#ifndef NSTRING_H
#define NSTRING_H
#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
typedef std::pair<std::string, int> psi;
// Only compare on the first element
bool operator==(const psi& l, const psi& r) {
return l.first == r.first;
}
class NString {
std::string s;
int thisOccurrence;
// Keep track of the number of occurrences:
typedef std::vector<psi> vp;
typedef vp::iterator vpit;
static vp words;
void addString(const std::string& x) {
psi p(x, 0);
vpit it = std::find(words.begin(), words.end(), p);
if(it != words.end())
thisOccurrence = ++it->second;
else {
thisOccurrence = 0;
words.push_back(p);
}
}
public:
NString() : thisOccurrence(0) {}
NString(const std::string& x) : s(x) { addString(x); }
NString(const char* x) : s(x) { addString(x); }
// Implicit operator= and copy-constructor are OK here.
friend std::ostream& operator<<(
std::ostream& os, const NString& ns) {
return os << ns.s << " [" << ns.thisOccurrence << "]";
}
// Need this for sorting. Notice it only
// compares strings, not occurrences:
friend bool
operator<(const NString& l, const NString& r) {
return l.s < r.s;
}
friend
bool operator==(const NString& l, const NString& r) {
return l.s == r.s;
}
// For sorting with greater<NString>:
friend bool
operator>(const NString& l, const NString& r) {
return l.s > r.s;
}
// To get at the string directly:
operator const std::string&() const { return s; }
};
// Because NString::vp is a template and we are using the
// inclusion model, it must be defined in this header file:
NString::vp NString::words;
#endif // NSTRING_H ///:~
//: C06:PrintSequence.h
// From "Thinking in C++, Volume 2", by Bruce Eckel & Chuck Allison.
// (c) 1995-2004 MindView, Inc. All Rights Reserved.
// See source code use permissions stated in the file 'License.txt',
// distributed with the code package available at www.MindView.net.
// Prints the contents of any sequence.
#ifndef PRINTSEQUENCE_H
#define PRINTSEQUENCE_H
#include <algorithm>
#include <iostream>
#include <iterator>
template<typename Iter>
void print(Iter first, Iter last, const char* nm = "",
const char* sep = "\n",
std::ostream& os = std::cout) {
if(nm != 0 && *nm != '\0')
os << nm << ": " << sep;
typedef typename
std::iterator_traits<Iter>::value_type T;
std::copy(first, last,
std::ostream_iterator<T>(std::cout, sep));
os << std::endl;
}
#endif // PRINTSEQUENCE_H ///:~