fleshbender
fleshbender

Reputation: 101

Sorting of two vectors separately?

I have to make a program which uses the following two vectors:-

vector<double> age;
vector<string> name;

I take their input separately. I have to make a function sort() such that it sorts name alphabetically and then reorganizes age accordingly to match name.

Please help!!

Upvotes: 2

Views: 101

Answers (3)

Jarod42
Jarod42

Reputation: 217275

If you can group them within struct or equivalent, you may create an additional vector for indexes that you sort and use for indirection:

std::vector<double> ages = /**/;
std::vector<string> names = /**/;
// ages.size() == names.size()
std::vector<std::size_t> indexes(names.size());
std::iota(indexes.begin(), indexes.end(), 0u);
std::sort(indexes.begin(), indexes.end(), [&](std::size_t lhs, std::size_t rhs) {
    return names[lhs] < names[rhs];
});

for (auto index : indexes) {
    std::cout << names[index] << " has " << ages[index] << std::endl;
}

And with range-v3 you can do:

std::vector<double> ages = /**/;
std::vector<string> names = /**/;
auto zip = ranges::view::zip(names, ages);

ranges::sort(zip);

for (const auto& z : zip) {
    std::cout << std::get<0>(z) << " " << std::get<1>(z) << std::endl;
}

Demo

Upvotes: 3

Trevir
Trevir

Reputation: 1313

Assuming you really need a function that takes two vectors and modifies them.

The sort function can be implemented as:

void sort ( vector<double>& ages, vector<string>& names)
{
     if ( ages.size() != names.size() )
         return;

     std::map< string, double > helper_map;
     for ( size_t id = 0; id < names.size(); ++id)
     {
         helper_map.emplace( names[id], ages[id] );
     }

     names.clear();
     ages.clear();

     for (const auto& helper : helper_map)
     {
          names.push_back( helper.first );
          ages.push_back( helper.second );
     } 
}

Working example: http://coliru.stacked-crooked.com/a/2457c832c0b612b2

However keep in mind that this problem should be solved using different approaches as pointed out in the comments. As homework those things don't always apply though.

Upvotes: 3

stefaanv
stefaanv

Reputation: 14392

If the sort function accepts both the vectors, the easiest way is to copy everything to std::set<std::pair<string,double>> which sorts first on name and then copy the sorted entries to the input vectors. If you can't use sets, you can use vector and sort yourself.

The reason is that sorting changes the order so you lose the link between the entries of both vectors. If you can't or won't use the combined set method, you need to make sure that the link is maintained in another way, probably via a temporary container with references.

Upvotes: 3

Related Questions