Let's consider if x = 9
and vector = {1, 8, 10, 16}
,
Then upper bound of x
in vector is 10
,
Now if you traversal toward begin
or toward end
of the vector
from upper bound
the distance will increase with respect to x
in both direction, because vector is sorted.
Following two step will produce required output,
- Find distance between x and left element, and between right element and x then if left distance is less then or equal to right distance then print left element otherwise print right element,
- If left element is printed then move one element previous to left element and if right element is printed then move next element from right element.
Now let`s apply these steps,
Here x = 9
, vector = {1, 8, 10, 16}
and upper bound = 10
- left element = 8, right element = 10
(9 - 8) <= (10 - 9) is true, so print 8, and now left element = 1
- left element = 1, right element = 10
(9 - 1) <= (10 - 9) is false, so print 10, and now right element = 16
- left element = 1, right element = 16
(9 - 1) <= (16 - 9) is false, so print 16, and now right element = end of
vector
- left element = 1, right element = end of vector
so print 1
These steps will produce expected output : {8, 10, 16, 1}
Try this implementation,
#include <iostream>
#include <vector>
#include <algorithm>
using std::cout;
template <typename ForwardIterator>
void print(ForwardIterator first, ForwardIterator last){
for(; last != first; ++first)
cout<< *first<< " ";
}
void printClostestFirst(const std::vector<int>& vec, const int piotValue){
std::vector<int>::const_iterator mid = std::upper_bound(vec.cbegin(), vec.cend(), piotValue);
if(vec.cend() == mid){
print(vec.crbegin(), vec.crend());
return;
}
else if(vec.begin() == mid){
print(vec.cbegin(), vec.cend());
return;
}
std::vector<int>::const_reverse_iterator left = vec.crbegin() + std::distance(mid, vec.cend());
std::vector<int>::const_iterator right = mid;
std::vector<int>::const_reverse_iterator leftEnd = vec.crend();
std::vector<int>::const_iterator rightEnd = vec.cend();
int leftDist = 0;
int rightDist = 0;
while(leftEnd != left && rightEnd != right){
leftDist = piotValue - *left;
rightDist = *right - piotValue;
if(leftDist <= rightDist){
cout<< *left<< " ";
++left;
}
else{
cout<< *right<< " ";
++right;
}
}
if(leftEnd != left)
print(left, leftEnd);
else
print(right, rightEnd);
}
int main(int , char *[]){
cout<< "x = 9 . . .vec = { 1, 8, 10, 16 } . . . output: { ";
printClostestFirst({1, 8, 10, 16}, 9);
cout<< "}\n";
cout<< "x = 15 . . .vec = { -100,1,12,15,100 } . . . output: { ";
printClostestFirst({-100,1,12,15,100}, 15);
cout<< "}\n";
cout<< "x = 99 . . .vec = { -100,1,12,15,100 } . . . output: { ";
printClostestFirst({-100,1,12,15,100}, 99);
cout<< "}\n";
cout<< "x = -1 . . .vec = { -100,1,12,15,100 } . . . output: { ";
printClostestFirst({-100,1,12,15,100}, -1);
cout<< "}\n";
cout<< "x = 0 . . .vec = { -100,1,12,15,100 } . . . output: { ";
printClostestFirst({-100,-50,50,100}, 0);
cout<< "}\n";
}
output:
x = 9 . . .vec = { 1, 8, 10, 16 } . . . output: { 8 10 16 1 }
x = 15 . . .vec = { -100,1,12,15,100 } . . . output: { 15 12 1 100 -100 }
x = 99 . . .vec = { -100,1,12,15,100 } . . . output: { 100 15 12 1 -100 }
x = -1 . . .vec = { -100,1,12,15,100 } . . . output: { 1 12 15 -100 100 }
x = 0 . . .vec = { -100,1,12,15,100 } . . . output: { -50 50 -100 100 }