对字符串数组进行自定义排序
Custom Sort on an array of Strings
给定一个包含彩虹七种颜色但按随机顺序排列的字符串数组,我应该以某种方式对该数组进行排序,以输出红色、橙色、绿色,。。。。,按顺序排列的是紫罗兰。彩虹颜色的顺序。如何对此数组进行排序?
您应该编写一个自定义比较器。以下是我的做法。
//somewhere in initalization code;
std::map<string, int> mapOrder;
mapOrder["red"] = 1;
mapOrder["orange"] = 2;
...
mapOrder["violet"] = 7;
bool isRainbowLess(const std::string& a, const std::string& b)
{
return mapOrder[a] < mapOrder[b];
}
int main()
{
std::vector<std::string> myVector;
....
std::sort(myVector.begin(), myVector.end(), &isRainbowLess);
}
此代码尚未完成。但你应该了解大致情况。我跳过的一件事是整数本身的排序。既然它应该是琐碎的。正如你所看到的,映射有点PIA,看起来很糟糕。但由于您禁止使用STL,因此没有std::map
。此外,我对所有表都隐含了N
的静态大小。它可以动态分配,没有问题,也没有std::vector
。
我对map*
函数使用了else if
s来模拟std::map
函数。也许可以使用switch ... case
,但它在一个不错的编译器上的工作原理应该基本相同。
我在下面写的代码在提供的功能方面与Armen的代码几乎相同。我会推荐他的解决方案。我跳过了相同的部分。所以你可以看到它更丑,更打字。它看起来几乎像纯C。如果你真的渴望在非常大的情况下达到速度,也许可以进行一次修改。这将使用一个临时数据结构来保存映射的值,对其进行排序,然后将其映射回。确切地说,我建议在高性能约束下避免在std::string
上调用map::operator[](const &T)
(或任何访问器),以避免哈希计算。但仅此而已。
还有一些问题需要讨论。比如,如果你想让两种颜色具有相同的值,或者使用非整数权重。基于STL的解决方案适应性更强。
/* This will map color literals (color names) to integers, which will associate them with
a numerical value, than can be used for comparison */
enum Colors { Red, Orange, Green, /*...*/ Violet };
/* this should read colors as std::string instances from the input array and assing
the the appropriate color codes into output array at corresponding indexes */
void mapString2Color( const std::string* input, int* output, size_t N ){
for(size_t i = 0; i < N; i++){
if ( input[i] == std::string("red") ) output[i] = Colors::Red;
else if ( input[i] == std::string("orange") ) { output[i] = Colors::Orange; }
else if ( input[i] == std::string("green") ) { output[i] = Colors::Green; }
/*...*/
else if ( input[i] == std::string("violet") ) { output[i] = Colors::Violet; }
else {/*unspecified color code */}
}
}
/* this is supposed to do the opposite to mapString (i.e. put appropriate
string at output[i] based on input[i]) */
void mapColor2String( const int* input, std::string* output, size_t N ){
for(size_t i = 0; i < N; i++){
if ( input[i] == Colors::Red ) output[i] = std::string("red");
else if ( input[i] == Colors::Orange ) { output[i] = std::string("orange"); }
else if ( input[i] == Colors::Green ) { output[i] = std::string("green"); }
/*...*/
else if ( input[i] == Colors::Violet ) { output[i] = std::string("violet"); }
else {/*unspecified color index*/}
}
}
void sort(int* array, size_t N){
/* any in-place sort of your liking for table of (unsigned) integers */
}
main(){
std::string[N] input_array;
std::string[N] output_array;
int[N] temp_array;
//map (translate) colors to their numerical values
mapString2Color(input_array, temp_array, N);
//sort it
sort(temp_array, N);
//map (translate) the values back to color names
mapColor2String(temp_array, output_array, N);
}
我要做的第一件事就是创建一个映射。您可以通过映射或线性迭代预排序的字符串数组并获取匹配条目的索引来实现这一点。一个非常简单的方法(实际上是为了演示的目的)可能只是将逻辑编码为一个封装的函数,如下所示:
int intForCol( const string& col )
{
if ( col == "red" ) return 0;
else if ( col == "orange" ) return 1;
else if ( col == "yellow" ) return 2;
else if ( col == "green" ) return 3;
else if ( col == "blue" ) return 4;
else if ( col == "indigo" ) return 5;
else if ( col == "violet" ) return 6;
throw "Invalid colour";
}
这将提供一个基于输入字符串的排序整数。下一步是创建一个比较器:
int colComp( const string& lhs, const string& rhs )
{
return intForCol( lhs ) - intForCol( rhs );
}
如果lhs
<rhs
,如果lhs
>rhs
则为阳性
现在,它可以相对容易地在STL中使用,既可以作为关联容器中的比较器,也可以直接在排序算法中使用。或者,如果使用STL是不可能的,或者这是为了了解排序是如何工作的,你可以像下面的简单且(非常)低效的算法一样实现自己的排序:
const int col_size = 7;
string input[col_size];
input[0] = "indigo";
input[1] = "green";
input[2] = "red";
input[3] = "blue";
input[4] = "yellow";
input[5] = "violet";
input[6] = "orange";
// simple bubble sort
int passes = col_size;
int last = col_size;
while ( passes-- )
{
for ( int i = 0; i < last - 1; ++i )
if ( colComp( input[i], input[i+1] ) > 0 )
{
string temp = input[i]; input[i] = input[i+1]; input[i+1] = temp;
}
last--;
}
- 从具有自定义排序的向量创建集合
- 自定义排序函数中的堆溢出
- 基于3个对象的自定义排序
- 如何将标准::矢量插入具有自定义排序功能的 std::set 中
- 在类中使用自定义排序时编译错误
- 如何自定义排序 VCL 列表框?
- 如何将比较器添加到自定义排序函数
- 自定义排序实现会导致链接错误
- 在hadoop 2.7.4的自定义排序类中调用C函数,给出Java.lang.unsatisfiedlinkerror
- C++中的多键自定义排序
- 对字符串数组进行自定义排序
- 如何使用list::sort()对STL列表对象进行排序,同时将自定义排序函数作为参数传递给list::排序
- 调用自定义排序函数的次数
- 自定义排序和映射时,首选函数指针或函数对象
- 使用std::sort与自定义排序对象和数据类型模板-寻找正确的语法
- STL 集自定义排序函数在 Qunicy 2005 中有效,但在 MS Studio 2010 中不起作用
- STL 设置自定义排序
- 具有自定义排序的C++映射中的唯一索引
- 使用Functor在集合中生成自定义排序方法
- 我的结构的自定义排序