Используя C ++ и, надеюсь, стандартную библиотеку, я хочу отсортировать последовательность выборок в порядке возрастания, но я также хочу запомнить исходные индексы новых выборок.
Например, у меня есть набор или вектор, или матрица образцов A : [5, 2, 1, 4, 3]
. Я хочу отсортировать их так, чтобы они были B : [1,2,3,4,5]
, но я также хочу запомнить исходные индексы значений, чтобы я мог получить другой набор, который будет:
C : [2, 1, 4, 3, 0 ]
- который соответствует индексу каждого элемента в 'B', в оригинале ' А».
Например, в Matlab вы можете сделать:
[a,b]=sort([5, 8, 7])
a = 5 7 8
b = 1 3 2
Кто-нибудь может увидеть хороший способ сделать это?
for (size_t i = 0; i != idx.size(); ++i) idx[i] = i;
я предпочитаю стандартstd::iota( idx.begin(), idx.end(), 0 );
#include <numeric>
для йота ()iota
наименее очевидно названный алгоритм из всей стандартной библиотеки C ++.Вы можете отсортировать std :: pair вместо просто int: первый int - исходные данные, второй int - исходный индекс. Затем укажите компаратор, который сортирует только по первому целому. Пример:
Сортируйте новый экземпляр задачи, используя компаратор, например:
Результат std :: sort для v_prime с использованием этого компаратора должен быть:
Вы можете очистить индексы, пройдя вектор, захватывая .second из каждой пары std ::.
источник
Предположим, что данный вектор
Создать новый вектор
Сортировка V и, сравнивая вместо сравнения элементов V, сравнивают соответствующие элементы A
источник
std::iota()
для более изящной инициализацииmap
Я написал общую версию индекса сортировки.
Использование такое же, как и в std :: sort, за исключением контейнера индекса для получения отсортированных индексов. тестирование:
вы должны получить 2 1 0 3. для компиляторов без поддержки c ++ 0x, замените выражение lamba как шаблон класса:
и переписать std :: sort как
источник
Теперь
a
содержит как наши значения, так и соответствующие им индексы в отсортированном виде.a[i].first = value
вi
«ом.a[i].second = idx
в исходном массиве.источник
Я столкнулся с этим вопросом и понял, что сортировка итераторов напрямую будет способом сортировки значений и отслеживания индексов; Нет необходимости определять дополнительный контейнер
pair
s of (value, index), который полезен, когда значения являются большими объектами; Итераторы обеспечивают доступ как к значению, так и к индексу:как для примера использования:
теперь, например, 5-й наименьший элемент в отсортированном векторе будет иметь значение,
**idx[ 5 ]
а его индекс в исходном векторе будетdistance( A.begin( ), *idx[ 5 ] )
или просто*idx[ 5 ] - A.begin( )
.источник
Есть еще один способ решить эту проблему, используя карту:
Это уничтожит неуникальные элементы. Если это не приемлемо, используйте мультикарту:
Чтобы вывести индексы, переберите карту или мультикарту:
источник
Прекрасное решение от @Lukasz Wiklendt! Хотя в моем случае мне нужно что-то более общее, поэтому я немного изменил:
Пример: Найти индексы, сортирующие вектор строк по длине, за исключением первого элемента, который является фиктивным.
печатает:
источник
Рассмотрите возможность использования
std::multimap
в соответствии с предложением @Ulrich Eckhardt. Просто код можно сделать еще проще.Дано
Сортировать в среднем времени вставки
Чтобы получить значения и оригинальные индексы
Причина предпочитают
std::multimap
кstd::map
, чтобы позволить одинаковые значения в исходных векторов. Также обратите внимание, что, в отличие отstd::map
,operator[]
не определено дляstd::multimap
.источник
Сделайте функцию
std::pair
in, затем сортируйте пару:общая версия:
ideone
источник
Являются ли элементы в векторе уникальными? Если это так, скопируйте вектор, отсортируйте одну из копий с помощью STL Sort, и вы сможете найти, какой индекс имел каждый элемент в исходном векторе.
Если вектор должен обрабатывать дубликаты, я думаю, вам лучше реализовать собственную процедуру сортировки.
источник
Ну, мое решение использует технику остатка. Мы можем поместить значения при сортировке в верхние 2 байта, а индексы элементов - в нижние 2 байта:
Затем отсортируйте массив
myints
как обычно:После этого вы можете получить доступ к индексам элементов через остаток. Следующий код печатает индексы значений, отсортированных в порядке возрастания:
Конечно, этот метод работает только для относительно небольших значений в исходном массиве
myints
(то есть тех, которые могут вмещаться в верхние 2 байтаint
). Но у этого есть дополнительное преимущество различения идентичных значенийmyints
: их индексы будут напечатаны в правильном порядке.источник
Если это возможно, вы можете построить массив позиций с помощью функции find, а затем отсортировать массив.
Или, может быть, вы можете использовать карту, где ключом будет элемент, а значения - список его позиций в следующих массивах (A, B и C)
Это зависит от последующего использования этих массивов.
источник
Для этого типа вопроса Сохраните данные массива оригиналов в новые данные, а затем выполните двоичный поиск первого элемента отсортированного массива в дублированном массиве, и этот индекс должен быть сохранен в векторе или массиве.
Здесь binarysearch - это функция, которая принимает массив, размер массива, элемент поиска и возвращает позицию искомого элемента.
источник
Есть много способов. Довольно простое решение - использовать 2D вектор.
Вот вывод:
источник