首页 > 解决方案 > 结构数组的 C++ 新顺序

问题描述

我有一个结构数组,其中每个结构都有一个 id (int) 和一个名为 aktiv (boolean) 的值。我想将结构数组传递给对结构进行排序的函数。数组中 aktiv 值为 0(假)的结构应该位于我的数组的末尾。

我以为我创建了第二个数组,我在其中临时保存我的值,然后将第二个数组中的所有内容再次放入第一个数组中,但它可以工作。我做错了什么或者我应该改变什么。提前致谢。我的代码:

void naende(Item itf[], int dim) { 
Item* temp_arr = new Item[dim]{};
int temp = 0;
for (int i = 0; i < dim; i++) {
    if (itf[i].aktiv == 0) {
        temp_arr[dim - i].id = itf[i].id;
        temp_arr[dim - i].aktiv = itf[i].aktiv;
        //cout << temp_arr[i].id << endl;
    }
    else if (itf[i].aktiv == 1) {
        temp_arr[temp].id = itf[i].id;
        temp_arr[temp].aktiv = itf[i].aktiv;
        temp++;
    }
}

for (int j = 0; j < dim; j++) {
    itf[j] = temp_arr[j];
}
}

标签: c++arraysfunctionsortingstructure

解决方案


鉴于您发布的内容,如果目标是将所有aktiv0 的项目移到数组的后面,则可以使用std::partition 。

#include <algorithm>

void naende(Item itf[], int dim) 
{ 
   std::partition(itf, itf + dim, [&](const Item& it) { return it.aktiv == 1; });
}

上面的代码将所有aktiv等于 1 的条目放在数组的左侧,将所有aktiv等于 0 的条目放在数组的右侧。

如果需要保持相对顺序,则可以使用std::stable_partition :

#include <algorithm>

void naende(Item itf[], int dim) 
{ 
   std::stable_partition(itf, itf + dim, [&](const Item& it) { return it.aktiv == 1; });
}

上面代码的重点是强调有 STL 算法或一组 STL 算法函数可以用来做很多工作,通常需要手动编码的解决方案(如果有则必须调试)错误)。使用上述函数,如果给定有效参数,STL 算法函数不会失败。


现在假设您不能使用std::partition,并且不需要保留订单。如果是这种情况,那么实现的方式可以是简单地拥有两个指针,并std::swap在战略时刻循环调用。

它的工作方式是您将有一个在数组中向前的索引,以及另一个从数组末尾开始并向后移动的索引。第一个索引的递增、结束索引的递减以及对的调用std::swap将通过以下方式完成:

#include <algorithm>
#include <iostream>

struct Item
{
    int id;
    int aktiv;
};

void naende(Item itf[], int dim)
{
    int leftpos = 0;
    int rightpos = dim - 1;
    while (leftpos < rightpos)
    {
        if (itf[leftpos].aktiv == 0)
        {
            std::swap(itf[leftpos], itf[rightpos]);
            --rightpos;
        }
        else
            ++leftpos;
    }
}

int main()
{
    Item item[] = { {1,1},{2,0},{34,0},{32,1},{12,0},{12,1},{21,1} };
    naende(item, 7);
    for (int i = 0; i < 7; ++i)
        std::cout << item[i].id << " " << item[i].aktiv << "\n";
}

输出:

1 1
21 1
12 1
32 1
12 0
34 0
2 0

如果我们检测到aktiv值为 1,我们基本上只使用 left 索引。如果不是1,那么我们通过与后面的项目交换将该项目放在后面,然后我们减少后面的项目索引。

对于稳定的项目,我将把它留作练习。


推荐阅读