Splitting an array of size N randomly into M fragments is nothing more than generating M - 1 non-repeating random numbers in the range [0, N-1) . Each such random number is a position after which the array is split.
For small source arrays, Knut's algorithm (?) Works fine, incl. because it immediately generates an ordered sequence of randomly selected values
// C++ #include <cstdlib> #include <vector> #include <iostream> unsigned random(unsigned n) { // Случайное число в диапазоне [0, n) return std::rand() % n; } int main() { std::vector<int> arr = { 1, 2, 3, 5, 6, 7, 8, 9, 0, 5, 6, 7, 8, 9, 2, 22 }; const unsigned N = arr.size(), M = 5; unsigned i = 0, n = N - 1, n_splits = M - 1; std::cout << "[ "; for (i = 0; i < n; ++i) { std::cout << arr[i] << " "; // Делаем в этом промежутке разрез с вероятностью // // осталось сделать разрезов n_splits // -------------------------------- = -------- // осталось просмотреть промежутков n - i // if (random(n - i) < n_splits) { std::cout << "][ "; --n_splits; } } std::cout << arr[i] << " ]"; }
Get
[ 1 2 3 5 6 ][ 7 8 ][ 9 0 ][ 5 6 7 8 9 2 ][ 22 ]