基于其他int数组排序
C++ Sort based on other int array
假设我有两个向量
std::vector<int>vec_int = {4,3,2,1,5};
std::vector<Obj*>vec_obj = {obj1,obj2,obj3,obj4,obj5};
我们如何根据vec_int的排序位置对vec_obj进行排序?所以目标可能是这样的:
std::vector<int>vec_int = {1,2,3,4,5};
std::vector<Obj*>vec_obj = {obj4,obj3,obj2,obj1,obj5};
我一直在尝试创建新的vec_array:
for (int i = 0; i < vec_int.size(); i++) {
new_vec.push_back(vec_obj[vec_int[i]]);
}
但我认为这不是正确的解决方案。我们该怎么做呢?由于
std库可能是最好的解决方案,但我找不到正确的解决方案来实现std::sort
您不必调用std::sort
,您需要的可以在线性时间内完成(前提是索引从1到N并且不重复)
std::vector<Obj*> new_vec(vec_obj.size());
for (size_t i = 0; i < vec_int.size(); ++i) {
new_vec[i] = vec_obj[vec_int[i] - 1];
}
但是对于这个解,当然你需要额外的new_vec
向量
如果索引是任意的并且/或者你不想分配另一个向量,你必须使用不同的数据结构:
typedef pair<int, Obj*> Item;
vector<Item> vec = {{4, obj1}, {3, obj2}, {2, obj3}, {1, obj4}, {5, obj5}};
std::sort(vec.begin(), vec.end(), [](const Item& l, const Item& r) -> bool {return l.first < r.first;});
也许有一个更好的解决方案,但我个人会使用std::map
中的项目自动按键排序的事实。这提供了以下可能性(未经测试!)
// The vectors have to be the same size for this to work!
if( vec_int.size() != vec_obj.size() ) { return 0; }
std::vector<int>::const_iterator intIt = vec_int.cbegin();
std::vector<Obj*>::const_iterator objIt = vec_obj.cbegin();
// Create a temporary map
std::map< int, Obj* > sorted_objects;
for(; intIt != vec_int.cend(); ++intIt, ++objIt )
{
sorted_objects[ *intIt ] = *objIt;
}
// Iterating through map will be in order of key
// so this adds the items to the vector in the desired order.
std::vector<Obj*> vec_obj_sorted;
for( std::map< int, Obj* >::const_iterator sortedIt = sorted_objects.cbegin();
sortedIt != sorted_objects.cend(); ++sortedIt )
{
vec_obj_sorted.push_back( sortedIt->second );
}
[不确定这是否适合您的用例,但是将元素放入映射中将默认存储按键排序的元素]
对于你的精确解决方案,如果创建新向量是一个问题,你可以使用一个简单的交换技巧(如选择排序)来避免这个问题
//Place ith element in its place, while swapping to its position the current element.
for (int i = 0; i < vec_int.size(); i++) {
if (vec_obj[i] != vec_obj[vec_int[i])
swap_elements(i,vec_obj[i],vec_obj[vec_int[i]])
}
这种方法的一般形式被称为"reorder according ",这是循环排序的一种变体。与您的示例不同,索引向量需要具有从0到size-1的值,而不是{4,3,2,1,5},它需要是{3,2,1,0,4}(否则必须调整下面的示例代码)。重新排序是通过根据索引向量或数组中的"循环"旋转元素组来完成的。(在我调整后的例子中有3个"循环",第一个循环:index[0] = 3, index[3] = 0。第二次循环:index[1] = 2, index[2] = 1。第三循环索引[4]= 4),在此过程中也对索引向量或数组进行排序。如果希望保留原始索引向量或数组,可以保存原始索引向量或数组的副本。在模板中根据vI重新排序vA的示例代码:
template <class T>
void reorder(vector<T>& vA, vector<size_t>& vI)
{
size_t i, j, k;
T t;
for(i = 0; i < vA.size(); i++){
if(i != vI[i]){
t = vA[i];
k = i;
while(i != (j = vI[k])){
// every move places a value in it's final location
vA[k] = vA[j];
vI[k] = k;
k = j;
}
vA[k] = t;
vI[k] = k;
}
}
}
仍然是简单的复制vA到另一个向量vB根据vI:
for(i = 0; i < vA.size(); i++){
vB[i] = vA[vI[i]];
- 按字符值访问int数组
- 将 int 数组转换为 std::vector<int*>
- 显示错误输出的简单数组排序程序
- C++,在int数组中输入字符串或字符会输出0,而不是ascii或error
- 整数区间(或 int 数组)中每个数字的出现次数
- Int 数组到C++容器
- C++ 未初始化的本地(非全局)int 数组中的元素类型到底是什么?
- 如何检测将文本文件读入 int 数组的新行
- C++快速将 int 数组内容转储到文本文件中
- <string> 如何在使用 SWIG 时将 int 数组和 List 作为参数传递给 C# C++
- 如何制作不允许重复值的 C++ int 数组循环?
- 如何将逗号分隔的文件读取为 2D int 数组?
- int 数组,但索引是字符?
- 使用可变参数函数将整数和/或整数数组放入单个 int 数组中
- 将 int 数组转换为带有小数C++的双精度数组
- 使用气泡排序从类中对 2D 字符和 Int 数组进行排序
- 我如何在INT数组上实现合并排序
- 将字符串数组和Int数组并排排序
- 基于其他int数组排序
- 如何声明一个将string和int数组一起排序的函数?