Pattern vector separation

I have a vector "a", which contains a huge amount of data and should be divided into two separate vectors "b" and "c".

vector<unsigned char> a; //contains a lot of data

vector<unsigned char> b; //data should be split into b and c
vector<unsigned char> c;

The data layout in the vector 'a' is as follows:

bbbbccccbbbbccccbbbbcccc

The first 4 bytes should go to the vector 'b', the next 4 bytes to the vector 'c', etc.

I could iterate over my data and push_back (or insert) each element into the corresponding vector (based on the index that they have in the vector "a"). However, I tried this and the result was very slow.

Is there a more efficient way in C ++ to achieve this?

+4
source share
3 answers

, , . , a , :

b.reserve(a.size() / 2);
c.reserve(a.size() / 2);
for (auto it = a.begin(); it < a.end(); it += 8) {
  b.insert(b.end(), it, it + 4);
  c.insert(c.end(), it + 4, it + 8);
}

a, , . , a :

b.reserve(a.size() / 2);
auto writer = a.begin();
for (auto reader = a.cbegin(); reader < a.cend(); reader += 8, writer += 4) {
  b.insert(b.end(), reader, reader + 4);
  std::copy(reader + 4, reader + 8, writer);
}
a.resize(a.size() / 2);
+9

, ChronoTrigger Update Answer, .

, , .

vector<T> a, :

1

K. K = 4 : BBBBCCCCBBBBCCCC

2

K. N = 24 = 6 * 4.

3

. b , , a. c.

( ... )

  • a , , - N
  • K
  • ,
    • BBBBCCCCBBBBCCCC CCCCCCCCBBBBBBBB

:

  • c
  • b a
  • 'a' 'c'

, , , ( 1/3 )

 void FastSplit(std::vector<int>& a, int stride)
 {
    auto asize = a.size();
    size_t j = asize-1;
    if ((asize / stride) % 2 == 1)
    {
       j -= stride;
       asize = asize - (asize+stride)/2; // asize now represents number of C elements
    }
    else
    {
        asize /= 2; // asize now represents number of C elements
    }

    for (size_t i=0; i < j; i+=stride, j-=stride)
    {
        for (size_t k = 0; k < stride; ++k, ++i, --j)
        {
            std::swap(a[i], a[j]);
        }
    }

Live Demo

4 ChronoTrigger T, 0.6T, 0.2T ( !)

, , , :

BBBBCCCCBBBB

, b c.


, sp2danny comment, , , O (n) , . ChronoTrigger.

, - ( -):

 // Slow!
 void StableSwappingSplit(std::vector<int>& a, int stride)
 {
    auto asize = a.size();

    auto starti = 0;
    while(starti < asize)
    {
        for (size_t i=starti, j = starti+stride;j < asize-starti; i+=stride, j+=stride)
        {
            for (size_t k = 0; k < stride; ++k, ++i, ++j)
            {
                std::swap(a[i], a[j]);
            }
        }
        starti += stride;
    }

    if ((asize / stride) % 2 == 1)
    {
       asize = asize - (asize+stride)/2; // asize now represents number of C elements
    }
    else
    {
        asize /= 2; // asize now represents number of C elements
    }
    //std::cout << "After swapping: \n";
    //PrintVec(a);

    std::vector<int> b(std::make_move_iterator(a.begin() + asize), std::make_move_iterator(a.end())); // copy second half into b
    a.resize(asize);
    //a is now c
 }
+5
vector<char>b(a.size()/2),c(a.size()/2);
for(auto i=a.begin();i<a.end();i=i+8){
    move(i,i+4,b.begin()+(i-a.begin())/2);
    move(i+4,i+8,c.begin()+(i-a.begin())/2);
}

. , B, - C, , b, 2.

0

Source: https://habr.com/ru/post/1607291/


All Articles