【问题标题】:sort indexes from a list with duplicates [duplicate]从具有重复项的列表中排序索引[重复]
【发布时间】:2019-03-13 08:22:30
【问题描述】:

我正在尝试获取列表中字符串的排序位置 可能包含重复。

我不关心重复的未定义顺序,但我想要一个全局排序。

这是我迄今为止最好的尝试:

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>

void display(const std::vector<int> &array)
{
  for (const auto & value : array)
    std::cout << value << " ";
  std::cout << std::endl;
}

std::vector<int> sortIndexes(const std::vector<std::string> &values)
{
  std::vector<int> indexes(values.size());
  std::iota(indexes.begin(), indexes.end(), 0);

  std::stable_sort(indexes.begin(), indexes.end(), [&values](const size_t first, const size_t second)
  {
    return values.at(first) <= values.at(second);
  });

  return indexes;
}

int main (void)
{
  display(sortIndexes({"b", "a", "c"})); // Expecting: 1 0 2           Result: 1 0 2 
  display(sortIndexes({"c", "c", "a"})); // Expecting: 1 2 0 or 2 1 0  Result: 2 1 0
  display(sortIndexes({"c", "a", "c"})); // Expecting: 1 0 2 or 2 0 1  Result: 1 2 0
  return 0;
}

还有其他方法可以获得预期的输出吗?

编辑:

我错过了解决我的问题的严格比较 + 'inverseIndexes' 部分。这是更新的代码:

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>

void display(const std::vector<int> & array)
{
  for (const auto & value : array)
    std::cout << value << " ";
  std::cout << std::endl;
}

std::vector<int> inverseIndexes(const std::vector<int> & indexes)
{
  std::vector<int> inverse(indexes.size());
  for (size_t i = 0; i < indexes.size(); ++i)
    inverse[indexes[i]] = i;
  return inverse;
}

std::vector<int> sortIndexes(const std::vector<std::string> & values)
{
  std::vector<int> indexes(values.size());
  std::iota(indexes.begin(), indexes.end(), 0);

  std::stable_sort(indexes.begin(), indexes.end(), [&values](const size_t first, const size_t second)
  {
    return values.at(first) < values.at(second);
  });

  return indexes;
}

int main (void)
{
  display(inverseIndexes(sortIndexes({"b", "a", "c"}))); 
  display(inverseIndexes(sortIndexes({"c", "c", "a"})));
  display(inverseIndexes(sortIndexes({"c", "a", "c"})));
  return 0;
}

【问题讨论】:

  • 您为什么希望1 2 0 成为第二次通话的可能性之一?为什么您认为2 0 1 会成为第三次通话的可能性之一?
  • std::stable_sort&lt; 做正确的事情,你只是有错误的期望。使用 &lt;= 时的行为未定义。很遗憾,您得到的结果根本没有,而不是一个响亮的错误。
  • 我希望 0 对应于“较小”字符,并且我希望重复项的行为未定义。在您的示例中,这将导致: [8; 之间的未定义序列; 20] 表示所有 'c',8 表示 'b' 和 [0; 之间的未定义序列; 7] 对于'a'
  • values[0] 不是a,那么为什么要把它包含在a 范围内呢? values[indexes[0]] a

标签: c++ sorting duplicates


【解决方案1】:

std::stable_sort 的比较函数应该是严格的“小于”,而不是“小于或等于”。所以,你只需要修复这一行:

    return values.at(first) < values.at(second);

【讨论】:

  • 但在这种情况下, {"c", "c", "a"} 的输出是 2 0 1 ...我认为我基本上需要一种不需要严格的排序弱排序。
  • 这些是正确(且稳定)排序数组的索引:2(a)、0(第一个c)、1(第二个c)。如果你想要它的倒数(看起来你想要),只需计算它:inverseIndices[indices[i]] = i;
  • 我不明白为什么'a'被认为'更大'(2)比两个'c'(0和1)
  • 您误解了 sort 的作用。当前输出显示“要获得一个排序数组,获取索引 2 处的字符串 ('a'),然后获取索引 0 处的字符串 ('c'),然后获取索引 1 处的字符串 ('c')”。你似乎想要别的东西:你想要一个输出说“第一个字符串 ('c') 将在排序数组的位置 1,第二个字符串 ('c') 将在位置 2 和第三个字符串 ( 'a') 将在位置 0"。你看得到差别吗?如前所述,您只需反转索引:inverseIndices[indices[i]] = i;
  • 就是这样!谢谢!
猜你喜欢
  • 2013-06-20
  • 2019-05-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-30
  • 1970-01-01
  • 1970-01-01
  • 2019-07-14
  • 1970-01-01
相关资源
最近更新 更多