, 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
:
, , , ( 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;
}
else
{
asize /= 2;
}
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.
, - ( -):
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;
}
else
{
asize /= 2;
}
std::vector<int> b(std::make_move_iterator(a.begin() + asize), std::make_move_iterator(a.end()));
a.resize(asize);
}