簡體   English   中英

將多個偏移量的多個元素插入向量中

[英]Insert multiple elements at multiple offsets into an vector

我有一個vector<uint32_t> values和一個vector<std::pair<uint32_t, uint_32_t>> updates ,其中包含對該向量的(大量)累積更新,我想盡可能便宜地實現它。

的更新{5, 12}應該插入12右后的values[5] 不涉及任何其它變型 ,即, values = {10,20,30}updates = {{0,5}, {1, 6}, {2, 7}} values = {10, 5, 20, 6, 30, 7}values = {10, 5, 20, 6, 30, 7}

我想根據updates向量來修改向量,如下所示:

static void update(std::vector<uint32_t>& values,
    std::vector<std::pair<uint32_t, uint32_t>> updates) {
    std::sort(updates.begin(), updates.end(),
        [](std::pair<uint32_t, uint32_t> a, std::pair<uint32_t, uint32_t> b){
             return a.first < b.first;
        });
    values.reserve(values.size()+updates.size());
    for(uint32_t i = 0; i < updates.size(); ++i){
        values.insert(values.begin()+i+updates[i].first, updates[i].second);
    }

}

如果我允許重復的update[i].first ,則需要使用std::stable_sort保持相對順序。

顯然,此代碼相當慢,使用O(n^2)時間一次將向量的其余部分移回一個。 應該有一個更好的解決方案。

已經有一個關於SO的問題,它非常相似:將多個值插入vector 雖然有一個我可以用來在O(1)空間和O(n)時間中更新向量的答案,但是使用c ++ 03時這個問題已經很老了,我想知道是否有一種現代的方法可以做到這一點(甚至,如果我可以避免事先調用std::sort )。

也許這樣的事情應該起作用。 由於我們知道所有更新,因此我們知道每個值必須偏移多少才能為新值騰出空間。 也就是說,數量恰好等於給定值具有較低索引的更新次數。 我們可以從后退,通過|updates|移動值 位置,插入具有最高索引的更新,將下一批移動|updates-1| 位置,插入第二高的更新...

static void update(std::vector<uint32_t>& values,
    std::vector<std::pair<uint32_t, uint32_t>> updates) {
    std::sort(updates.begin(), updates.end(),[](auto a, auto b){
             return a.first > b.first;//From highest to lowest indices.
        });

    const std::size_t N = values.size();
    std::size_t K = updates.size();
    values.resize(N+K);
    std::size_t end = N;
    for(auto [i,v]:updates){
        //Shift the values in [i+1,end) K positions right
        std::move_backward(values.begin()+i+1,
                           values.begin()+end,
                           values.begin()+end+K);
        //Insert the update
        values[i+K]=v;
        //Preceding values are shifted only by K-1 positions
        --K;
        //Already shifted values
        end=i+1;
    }
}

這需要O(u log u)對更新進行排序,並需要O(u+n)對舊數據進行移位並添加新值。 resize了一個resize 請注意,將resize為零會初始化添加的值,此處原始數組的效率會稍高一些。 或者使用emplace_back做一些索引魔術。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM