给定一个包含七种颜色的彩虹但按随机顺序放置的字符串数组,我不知何故应该按此顺序对此数组进行排序以输出红色,橙色,绿色,......,紫色。彩虹色的顺序。我该如何排序这个数组?
答案 0 :(得分:4)
你应该写一个自定义比较器。这就是我要怎么做的。
//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);
}
答案 1 :(得分:1)
好的,请不要马上投票。我知道这是一个不好的例子。我写的是因为OP特别要求提供无STL解决方案,并提出(坏)会/它的样子。
嗯,你去吧。代码未完成。但你应该得到一般的想法。我跳过的一件事就是对整数本身进行排序。既然它应该是微不足道的。正如你所看到的,映射是PIA的一点点,看起来很糟糕。但是因为你禁止使用STL,所以没有std::map
。此外,我暗示所有表的静态大小为N
。它可以动态分配,没有问题,也没有std::vector
。
我使用else if
个map*
函数来模仿std::map
功能。可能会使用switch ... case
,但它应该在一个体面的编译器上工作几乎相同。
我在下面写的代码与Armen的功能几乎相同。我会推荐他的解决方案。我跳过了相同的部分。所以你可以看到它更丑陋和更多打字。它看起来几乎像纯C.如果你真的渴望在非常大的情况下速度,可能会有一个修改。那将是一个临时数据结构,它将保存映射值,对其进行排序,然后将其映射回来。确切地说,我建议在高性能约束下避免在map::operator[](const &T)
上调用std::string
(或任何访问者)以避免哈希计算。但那只是它。
还有一些需要讨论的内容。就像你想要两种颜色具有相同的值,或者使用非整数权重一样。基于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);
}
答案 2 :(得分:0)
我要做的第一件事就是创建一个映射。您可以通过映射或线性迭代预先排序的字符串数组并获取匹配条目的索引来执行此操作。一个非常简单的方法(实际上用于演示目的)可能只是将逻辑编码为封装函数,如下所示:
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
&lt; rhs
&lt;如果lhs
&gt; rhs
,则为正{} 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--;
}
现在可以在STL中使用 - 作为关联容器中的比较器或直接在排序算法中 - 相对容易。或者,如果使用STL是不可能的,或者这是为了理解排序是如何工作的,那么您可以实现自己的排序,如下面的简单和(非常)低效算法:
{{1}}