我有一个大小为10的std::vector<int>
,每个条目最初为-1。此向量代表我的游戏排行榜(高分),-1表示该条目没有得分。
std::vector<int> myVector;
myVector.resize(10, -1);
当游戏开始时,我想从文件中加载高分。我加载每一行(最多10行),将找到的值转换为int
std::stoi
,如果数字> 0,我将其替换为当前在向量中的-1在当前位置。
这一切都有效。现在问题是:
由于文件中的值不一定要排序,我想在加载所有条目后对myVector
进行排序。我这样做
std::sort(myVector.begin(), myVector.end());
按升序对其进行排序(在我的游戏中得分越低)。
问题在于,由于向量最初用-1填充,并且高分文件中不一定保存10个条目,因此除了玩家的分数之外,向量可能还包含几个-1。
这意味着当使用上面的代码对矢量进行排序时,所有-1将出现在玩家的分数之前。
我的问题是:如何对矢量进行排序(按升序排列),但所有带-1的条目都将放在最后(因为它们不代表真实分数)?
答案 0 :(得分:9)
结合分区和排序:
std::sort(v.begin(),
std::partition(v.begin(), v.end(), [](int n){ return n != -1; }));
如果存储从partition
返回的迭代器,则您已经完整地描述了非平凡值的范围,因此您不需要在以后查找-1。
答案 1 :(得分:3)
您可以提供lambda作为sort的参数:
std::sort(myVector.begin(), myVector.end(),[]( int i1, int i2 ) {
if( i1 == -1 ) return false;
if( i2 == -1 ) return true;
return i1 < i2; }
);
这里是demo(从Kerrek复制)
但目前尚不清楚你是如何意识到排序后得分在哪里的。
答案 2 :(得分:2)
根据您的描述,分数似乎永远不会消极。在这种情况下,我建议将得分设为vector
unsigned int
。您可以定义常量
const unsigned int INFINITY = -1;
并最初使用INFINITY
加载矢量。 INFINITY
是可以存储在32位无符号整数中的最大正整数(也与2的补码中的-1
对应)
然后你可以简单地使用
排序sort(v.begin(),v.end());
所有INFINITY
将在排序后结束。
答案 3 :(得分:0)
std::sort
的 bool cmp(const T& a, const T& b);
supports using your own comparison function。所以编写自己的函数类似于:
bool sort_negatives(const int& a, const int& b)
{
if (a == -1) {
return false;
}
if (b == -1) {
return true;
}
return a < b;
}
然后像sort
一样致电std::sort(myVector.begin(), myVector.end(), sort_negatives);
。
编辑:修正了斯拉瓦的逻辑礼貌。如果您使用的是支持C ++ 11的编译器,请使用lambda或分区答案,但这应该适用于C ++ 11之前的编译器。
答案 4 :(得分:0)
对于以下内容,我假设-1
值都放在向量的末尾。如果不是,请使用KerrekSB的方法,或者确保不跳过向量中没有有效分数的索引(通过使用额外的索引/迭代器来写入向量)。
std::sort
使用一对迭代器。只需提供包含非-1
值的子范围。从文件中读取后,您已经知道此范围的结束。如果您已经使用迭代器来填充向量,就像在
auto it = myVector.begin();
while (...) {
*it = stoi(...);
++it;
}
然后只需使用it
代替myVector.end()
:
std::sort(myVector.begin(), it);
否则(即,当使用索引填充向量时,假设i
是值的数量),使用
std::sort(myVector.begin(), myVector.begin() + i);
答案 5 :(得分:0)
另一种方法是使用reserve()
代替resize()
。
std::vector<int> myVector;
myVector.reserve(10);
for each line in file:
int number_in_line = ...;
myVector.push_back(number_in_line);
std::sort(myVector.begin(), myVector.end());
这样,向量将只有实际存在的数字,没有额外的(虚假的)值(例如-1)。如果向量需要稍后传递给其他模块或函数进行进一步处理,则不需要知道'-1'值的特殊性。