使用STL通用算法stable_partition()和list成员函数splice()来划分一个list
我们将完成一个稍微有点复杂的例子。它演示STL通用算法stable_partition()算法和一个list成员函数 splice()的变化。注意函数对象的使用和没有使用循环。 通过简单的语句调用STL算法来控制。
stable_partition()是一个有趣的函数。它重新排列元素,使得满足指定条件的元素排在 不满足条件的元素前面。它维持着两组元素的顺序关系。
splice 把另一个list中的元素结合到一个list中。它从源list中删除元素。
在这个例子中,我们想从命令行接收一些标志和四个文件名。文件名必须’按顺序出现。通过使用stable_partition() 我们可以接收和文件名混为任何位置的标志,并且不打乱文件名的顺序就把它们放到一起。
由于记数和查找算法都很易用,我们调用这些算法来决定哪个标志被设置而哪个标志未被设置。 我发现容器用来管理少量的象这样的动态数据。
/*
|| Using the STL stable_partition algorithm
|| Takes any number of flags on the command line and
|| four filenames in order.
*/
#include <string>
#include <list>
#include <algorithm>
PrintIt ( string& AString { cout << AString << endl; }
class IsAFlag {
public:
bool operator () (string& PossibleFlag) {
return PossibleFlag.substr(0,1)=="-";
}
};
class IsAFileName {
public:
bool operator () (string& StringToCheck) {
return !IsAFlag()(StringToCheck);
}
};
class IsHelpFlag {
public:
bool operator () (string& PossibleHelpFlag) {
return PossibleHelpFlag=="-h";
}
};
int main (int argc, char *argv[]) {
list<string> CmdLineParameters; // the command line parameters
list<string>::iterator StartOfFiles; // start of filenames
list<string> Flags; // list of flags
list<string> FileNames; // list of filenames
for (int i = 0; i < argc; ++i) CmdLineParameters.push_back(argv[i]);
CmdLineParameters.pop_front(); // we don't want the program name
// make sure we have the four mandatory file names
int NumberOfFiles(0);
count_if(CmdLineParameters.begin(), CmdLineParameters.end(), IsAFileName(), NumberOfFiles);
cout << "The " << (NumberOfFiles == 4 "correct " : "wrong ") << "number (" << NumberOfFiles << ") of file names were specified" << endl;
// move any flags to the beginning
StartOfFiles = stable_partition(CmdLineParameters.begin(), CmdLineParameters.end(), IsAFlag());
cout << "Command line parameters after stable partition" << endl;
for_each(CmdLineParameters.begin(), CmdLineParameters.end(), PrintIt);
// Splice any flags from the original CmdLineParameters list into Flags list.
Flags.splice(Flags.begin(), CmdLineParameters, CmdLineParameters.begin(), StartOfFiles);
if (!Flags.empty()) {
cout << "Flags specified were:" << endl;
for_each(Flags.begin(), Flags.end(), PrintIt);
}
else {
cout << "No flags were specified" << endl;
}
// parameters list now contains only filenames. Splice them into FileNames list.
FileNames.splice(FileNames.begin(), CmdLineParameters, CmdLineParameters.begin(), CmdLineParameters.end());
if (!FileNames.empty()) {
cout << "Files specified (in order) were:" << endl;
for_each(FileNames.begin(), FileNames.end(), PrintIt);
}
else {
cout << "No files were specified" << endl;
}
// check if the help flag was specified
if (find_if(Flags.begin(), Flags.end(), IsHelpFlag())!=Flags.end()) {
cout << "The help flag was specified" << endl;
}
// open the files and do whatever you do
}
给出这样的命令行:
test17 -w linux -o is -w great
输出是:
The wrong number (3) of file names were specified
Command line parameters after stable partition
-w
-o
-w
linux
is
great
Flags specified were:
-w
-o
-w
Files specified (in order) were:
linux
is
great