#include <iostream>
#include <vector>
#include <iterator>
#include <string>
#include <algorithm>
#include <numeric>

using namespace std;

template<typename It>
void replace(
	It beg, 
	It end, 
	typename iterator_traits<It>::value_type const& oldval, 
	typename iterator_traits<It>::value_type const& newval)
{
	while ((beg = find(beg, end, oldval)) != end)
	{
		*beg = newval;
		++beg;
	}
}

template<typename T>
void rearrange_vector(vector<int> nInd, vector<T> &v)
{
	size_t indx; 
	for (size_t ie(v.size()), i(0); i < ie; ++i)
	{
		auto it = find(nInd.begin(), nInd.end(), i);
		if (nInd.end() != it)
		{
			indx = distance(nInd.begin(), it);
			swap(v.at(i), v.at(indx));
			replace(nInd.begin(), nInd.end(), indx, i);
		}
	}
}

int main() 
{
	vector<string> firstnames = { "Bjarne",     "Alexander",  "Dennis",   "James",   "James"   };
    vector<string> lastnames  = { "Stroustrup", "Stepanov",   "Ritchie",  "Coplien", "Gosling" };
    
    vector<int> indices(firstnames.size());
    iota(indices.begin(), indices.end(), 0);
    
    sort(indices.begin(), indices.end(), [&](int i1, int i2){
    	return firstnames[i1] < firstnames[i2]; 
    });
    
    rearrange_vector(indices, firstnames);
    rearrange_vector(indices, lastnames);
    
    for (size_t i(0), ie(firstnames.size()); i < ie; ++i)
    {
    	cout << firstnames[i] << " " << lastnames[i] << endl;
    }

	return 0;
}