Способ замены одного вектора на другой - PullRequest
0 голосов
/ 06 июля 2018

Я сортирую 2 вектора, используя вектор индекса.

2 вектора имеют разный размер. Один вектор (ключи) имеет размер X, а другой (дескрипторы) - размер X * 128 (один ключ параметризован 128 значениями).

Чтобы создать вектор индекса, я сгенерировал вектор без знака и использовал функцию йоты для вставки в этот вектор [0,1,2, ..., X] затем я использую функцию сортировки для сортировки этих индексов в зависимости от масштаба клавиши (keys [i] .s).

После этого я генерирую другой вектор, в котором я копирую значения, используя вектор индекса для дескрипторов и ключей (называя их descriptors_tmp и keys_tmp), а затем хочу сделать первый вектор ключей равным keys_tmp, и то же самое для дескрипторов равно descriptors_tmp. Мой вопрос:

-Есть способ сделать это без копирования. Поскольку мне не нужна предыдущая версия ключей и дескрипторов, я мог бы просто указать вектор на другом векторе (что-то вроде * keys = * keys_tmp)?

- Есть ли более простой способ достичь того, чего я пытаюсь достичь?

Мой код:

void _siftMatch::getIdxOfSorting(std::vector<unsigned>& idx_scale_order)
{
    //keys[i].s is the scale and I sort depending decreasing scale
    auto cmp_scale = [this](int i, int j) {
        return keys[i].s > keys[j].s;
    };

    std::sort(idx_scale_order.begin(), idx_scale_order.end(), cmp_scale);
}   

void _siftMatch::sort() {
    //vector containing the index of sorted
    std::vector<unsigned>idx_scale_order;
    idx_scale_order.resize(keys.size());
    //Generate [0,1,...,X]
    std::iota(idx_scale_order.begin(), idx_scale_order.end(), 0); 

    //Sort the vector
    getIdxOfSorting(idx_scale_order); 

    std::vector<float> descriptors_tmp;
    std::vector<SiftGPU::SiftKeypoint> keys_tmp;

    for (int i = 0; i < idx_scale_order.size(); ++i) {
        keys_tmp.push_back(keys[idx_scale_order[i]]);
        for (int j = 0; j < 128; ++j)
            descriptors_tmp.push_back(descriptors[idx_scale_order[i] * 128 + j]);
     }
    //This is here that I want to put descriptors_tmp and keys_tmp in descriptors and keys
    //descriptors.swap(descriptors_tmp.data);
}

1 Ответ

0 голосов
/ 08 июля 2018

Есть ли способ сделать это без копирования

Этот пример сортировки 3 массивов по одному из массивов с использованием 4-го сгенерированного массива индексов, отсортированных по одному из 3 массивов, может помочь. Ключевой частью этого является переупорядочение всех четырех массивов в соответствии с массивом индексов. Вам нужно будет изменить это для вашей ситуации. Я не уверен, почему вы конвертируете массив индексов в массив числовых строк (через вызовы itoa), использование индексов напрямую работает лучше для примера в этом ответе.

// sort 3 vectors according to one of them

#include <algorithm>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>

int main()
{
    std::vector <int> A;                // ages
    std::vector <std::string> N;        // names
    std::vector <int> Z;                // zip codes
    std::vector <size_t> I;             // indices
    int tA;
    std::string tN;
    int tZ;

    A.push_back(37);
    N.push_back("Ted");
    Z.push_back(54211);
    A.push_back(21);
    N.push_back("John");
    Z.push_back(53421);
    A.push_back(31);
    N.push_back("Fred");
    Z.push_back(52422);
    A.push_back(21);
    N.push_back("Sam");
    Z.push_back(51422);
    // display the vectors
    for(size_t i = 0; i < A.size(); i++)
        std::cout << std::setw(6) << N[i]
            << std::setw(8) << Z[i]
            << std::setw(4) << A[i] << std::endl;
    std::cout << std::endl;
    // initialize the vector of indices
    for(size_t i = 0; i < A.size(); i++)
        I.push_back(i);
    // sort I according to A
    std::stable_sort(I.begin(), I.end(),
        [&A](size_t i, size_t j) {return 
        A[i] < A[j];});
    // reorder A, N, Z in place also restore I
    // time complexity is O(n)
    for(size_t i = 0; i < A.size(); i++){
        size_t j, k;
        if(i != I[i]){
            tA = A[i];
            tN = N[i];
            tZ = Z[i];
            k = i;
            while(i != (j = I[k])){
                A[k] = A[j];
                N[k] = N[j];
                Z[k] = Z[j];
                I[k] = k;
                k = j;
            }
            A[k] = tA;
            N[k] = tN;
            Z[k] = tZ;
            I[k] = k;
        }
    }
    // display the sorted vectors
    for(size_t i = 0; i < A.size(); i++)
        std::cout << std::setw(6) << N[i]
            << std::setw(8) << Z[i]
            << std::setw(4) << A[i] << std::endl;
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...