Reputation: 161
Need to move all values which is less than 1 in begin of array (WITHOUT SORT, and need solution without second array)
for example:
START ARRAY: {-2.12, -3, 7.36, 6.83, -1.82, 7.01}
FINISH ARRAY: {-2.12, -3, -1.82, 7.36, 6.83, 7.01}
There is my solution but it doesn't work very well, because at final we receive:
FINISH ARRAY: {-2.12, -3, -1.82, 6.83, 7.36, 7.01}
Values which less than 1, moves to begin of array, but 4 and 5 elements not in correct order
#include <iostream>
using namespace std;
int main() {
double arr[6] = {-2.12, -3, 7.36, 6.83, -1.82, 7.01};
cout << "Start array: " << endl;
for (int x = 0; x < 6; x++) {
cout << arr[x] << ", ";
}
int index=0;
double temp;
for (int i = 0; i < 6; i++) {
if (arr[i] < 1) {
temp=arr[i];
arr[i] = arr[index];
arr[index] = temp;
index++;
}
}
cout << endl << "FINISH ARRAY: " << endl;
for (int x = 0; x < 6; x++) {
cout << arr[x] << ", ";
}
return 0;
}
Upvotes: 2
Views: 195
Reputation: 26282
std::stable_partition(std::begin(arr), std::end(arr),
[](double d) { return d < 1; });
If you want to implement it yourself, note, that in-place stable partition (using comparisons and swaps) cannot be done better than in O(N log N)
time. Any algorithm with O(N)
running time is incorrect.
One possible solution can be obtained with divide-and-conquer approach:
template<class It, class Pred>
It stable_partition(It first, It last, Pred pred) {
// returns the iterator to the first element of the second group:
// TTTTTFFFFFF
// ^ return value
if (first == last)
return last;
if (last - first == 1) {
if (pred(*first)) // T
return last; // ^ last
else // F
return first; // ^ first
}
// Split in two halves
const auto mid = first + (last - first) / 2;
// Partition the left half
const auto left = stable_partition(first, mid, pred);
// TTTTTFFFFF
// ^ left
// ^ mid
// Partition the right half
const auto right = stable_partition(mid, last, pred);
// TTTTTFFFFF
// ^ right
// ^ mid
// Rotate the middle part: TTTTTFFFFFTTTTTFFFFF
// ~~~~~~~~~~
// ^ left ^ right
// ^ mid
const auto it = std::rotate(left, mid, right);
// TTTTTTTTTTFFFFFFFFFF
// ^ it
return it;
}
It resembles quicksort, but here we do not actually sort the range. std::rotate
itself can be easily implemented via three reverses.
Upvotes: 5