Я пытаюсь получить отсортированную позицию строки в списке которые могут содержать дубликаты.
Меня не волнует неопределенный порядок дубликатов, но мне нужна глобальная сортировка.
Вот моя лучшая попытка:
#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;
}
std::stable_sort поступает правильно с <, у вас просто неверные ожидания. Поведение при использовании <= не определено. Обидно, что вместо громкой ошибки вы получаете результат вообще.
Я ожидаю, что 0 соответствует «меньшему» символу, и ожидаю неопределенного поведения для дубликатов. В вашем примере это приведет к: неопределенной последовательности между [8; 20] для всех «c», 8 для «b» и неопределенной последовательности между [0; 7] для "а"
values[0] не является a, так почему он должен быть включен в диапазон a? values[indexes[0]]являетсяaИзвините, в приведенном вами примере результат удовлетворительный и я ищу. Однако я не понимаю результат '{"c", "c", "a"}', который равен '2 0 1' => почему у нас нет '1 2 0'?
Опять же, вы должны смотреть на values[indexes[n]], а не на values[n]. a является последним элементом в позиции 2, тогда у вас есть возрастающая последовательность положений c. Что вы ожидаете от разыменований на c a c





Функция сравнения для 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)
Вы неправильно понимаете, что делает этот вид. Текущий вывод говорит: «Чтобы получить отсортированный массив, возьмите строку с индексом 2 ('a'), затем строку с индексом 0 ('c'), затем строку с индексом 1 ('c')». Кажется, вам нужно что-то еще: вам нужен вывод, в котором говорится: «Первая строка ('c') будет в позиции 1 отсортированного массива, вторая строка ('c') будет в позиции 2, а третья строка ( 'a') будет в позиции 0 ". Вы видите разницу? Как уже упоминалось, вам нужно только инвертировать индексы: inverseIndices[indices[i]] = i;
Вот и все! Спасибо !
Почему вы ожидаете, что
1 2 0станет одной из возможностей для второго звонка? Почему вы ожидаете, что2 0 1станет одной из возможностей для третьего звонка?