【问题标题】:How do I sort not the elements of an array, but it's indexes? [duplicate]如何排序不是数组的元素,而是索引? [复制]
【发布时间】:2018-05-04 22:38:18
【问题描述】:

所以我有一个这样的数组:

int array[]={2, 4, 3, 1};

我想按降序排序,但获取原始索引,如下所示: {1, 2, 0, 3} 我该如何解决这个问题,以便它适用于任何大小的数组? 另外,有没有不需要C++11的解决方案?

谢谢!

【问题讨论】:

  • 你能详细说明这个问题吗?
  • 不清楚是什么问题。
  • 你真正想要什么?

标签: c++


【解决方案1】:

如果我对您的理解正确,您希望获得一份索引列表。一种解决方案是创建所有元素的索引的无序列表并对其进行排序。

int array[] = {2, 4, 3, 1};
int indices[] = {0, 1, 2, 3};

std::sort(indices, indices + 4, [&](int a, int b) {
    return array[b] < array[a];
});

由于您要求使用非 C++11 方式,因此您可以绕过 lambda 表达式,如下所示:

int array[] = {2, 4, 3, 1};
int indices[] = {0, 1, 2, 3};

struct {
    int *array;
    bool operator()(int a, int b) const
    {
        return this->array[b] < this->array[a];
    }
} customLess = {array};

std::sort(indices, indices + 4, customLess);

两种实现都会对indices 的值进行排序,但不是 array 本身。结果如下所示:

array == {2, 4, 3, 1}
indices == {1, 2, 0, 3}

【讨论】:

    【解决方案2】:

    有一个棘手而简单的解决方法:首先你有一个未排序的数组,所以创建一个索引数组{0, 1, 2, 3},然后使用循环对值数组进行排序,同时根据数组交换索引数组的元素价值观:

    int array[] = {2, 4, 3, 1};
    int indexes[] = {0, 1, 2, 3};
    
    for(int i(0); i < 4; i++){
        for(int j(i + 1); j < 4; j++){
            if(array[i] < array[j]){
    
                //sorting values
                array[i] ^= array[j];
                array[j] ^= array[i];
                array[i] ^= array[j];
    
                // sorting indexes
                indexes[i] ^= indexes[j];
                indexes[j] ^= indexes[i];
                indexes[i] ^= indexes[j];
            }
        }
    }
    
    cout << endl;
    for(int i = 0; i < 4; i++)
        cout << array[i] << ", ";
    cout << endl;
    
    for(int i = 0; i < 4; i++)
        cout << indexes[i] << ", ";
    

    我使用xor 对数组进行排序,但是您可以使用临时变量:

    int tmp = array[i]; 
    array[i] = array[j];
    array[j] = tmp;
    
    tmp = indexes[i];
    indexes[i] = indexes[j];
    indexes[j] = tmp;
    

    输出:

    4, 3, 2, 1,
    1, 2, 0, 3,
    

    【讨论】:

      【解决方案3】:

      我会选择这样的:

      std::vector<std::pair<int, int>> temp ;
      int idx = 0 ;
      for (auto x : array)
          temp.push_back(std::make_pair(x, idx++)) ;
      std::sort(temp.begin(), temp.end()) ;
      

      您可以轻松摆脱范围 for(这里使用的唯一 C++11 构造)。 std::pair 无需定义比较,默认即可。

      【讨论】:

      • 不太好,他们想要“降序”。
      【解决方案4】:

      您必须将初始索引保存在某处。 一种解决方案是使用结构。有点像这样:

      struct IndexInt
      {
          int index;
          int value;
      
      } typename IndexInt_t
      
      IndexInt_t array[]={{1,2}, {2,4}, {3,3}, {4,1}};
      

      现在您可以在array[i].value 之后排序并通过array[i].index 访问源索引。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-02
        • 1970-01-01
        • 1970-01-01
        • 2022-10-02
        • 2017-02-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多