簡體   English   中英

按元素原始位置的奇偶校驗穩定分區 std::vector

[英]Stable partition std::vector by the parity of the element's original position

我想通過容器中元素原始索引的奇偶校驗對std::vector進行分區。 換句話說,我想把它分成兩半:第一部分包含所有偶數索引元素,第二部分包含所有奇數索引元素。

元素之間的排序關系無關緊要,重要的是原始向量中的位置。

我想用標准算法和 lambdas 來實現這種效果,最好是在原位。 我可以用常規的for循環來做到這一點。

例子

讓我們假設我們有一個元素向量abcdef 所需的分區是acebdf 第一個 ( a )、第三個 ( c ) 和第五個 ( e ) 元素移到前面,而第二個 ( b )、第四個 ( d ) 和第六個 ( f ) 元素移到后面。

我的嘗試

我有一個類似於這個的對象:

struct T {
    int x;
};

我能夠通過這樣的字段值對其進行分區:

std::vector<T> ts {{1}, {2}, {4}, {3}, {6}, {5}};
auto predicate = [](const T& t) {
    return t.x % 2 == 1;
};
std::stable_partition(ts.begin(), ts.end(), predicate);

結果是1 3 5 2 4 6 我希望分區返回1 4 6 2 3 5

我試圖將predicate定義為

auto predicate = [](const std::vector<T>::const_iterator& t)
    return t->x % 2 == 1;
};

但它不會編譯,而且顯然沒有任何意義。

為了說明我的問題,我編寫了一個for循環來執行此分區,盡管不是以穩定的方式進行。

for (auto i = ts.begin() + 1, j = ts.begin() + 2; j != ts.end(); i += 1, j += 2) {
    std::swap(*i, *j);
}

概括

是否可以使用std算法實現它,或者我是否需要訴諸標准循環?

在 c++11 中,使用計數器作為索引來驗證它是偶數還是奇數。

#include <iostream>
#include <vector>

struct T {
    int x;
};

int main()
{
    std::vector<T> ts {{1}, {2}, {4}, {3}, {6}, {5}};
    int counter =0;
    auto predicate = [&counter]() {
        ++counter;
        return (counter % 2 == 1);
    };
    std::stable_partition(ts.begin(), ts.end(), predicate);

    for(auto i: ts)
        std::cout << i.x << ", ";

}

Vector 將其數據存儲在線性數組中。 你可以使用這些知識。

使 lambda 作為謂詞,它捕獲指向向量第一項的指針,並通過引用T 來獲取其參數,以引用向量的原始存儲元素。 然后您可以通過簡單的指針算法找出索引是否為偶數/奇數:

struct T {
    int x;
};
int main() {
    std::vector<T> ts {{1}, {2}, {4}, {3}, {6}, {5}};

    auto pred = [beg = &(*ts.begin())](T& elem) {
        return (&elem-beg) % 2 == 0;
    };

    std::stable_partition(ts.begin(), ts.end(), pred);
    for (T t : ts)
        std::cout << t.x << std::endl;
    // 1,4,6,2,3,5
}

暫無
暫無

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

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