0

I created this little project in C++ for a basketball 'gameish' thing. One thing I wanted to implement was a funciton that allowed one to see who had the highest or lowest stats out of all of the players, in this case, specifically, points per game (ppg). I broke up the stat components of the players and the names of the players into two different vectors, vector <vector <string> > names and vector <vector <double>> stats. I made it so that names[0] correlated to stats[0], so LeBron and his stats would be represented by say 1. I figured out how to sort the vectors by descending or ascending order, but when I sort a vector, say stats[0], the order is now different from the original order, and so it doesn't align with names[0]. So when I print stats[0][i] belongs to names[0][i] it no longer is true, as the two are no longer 'connected'. I've tried to troubleshoot this myself first, but came up empty, and then tried searching online for an answer which I haven't found, perhaps I didn't look hard enough. What do I do to make it so that the now mixed-up order of the stats vector can be written out correctly?

This code I created, seen below, works sometimes, for ppg it works until around 20. I tried to create it so that you could use any vector .

void sorting_test(bool ascend, int number, vector <double> statistic) {
        vector <vector <double>> ppg_desc {
            {},//ppg
            {},//slot
            {},//locked
        };
        //
        for (int i = 0; i < statistic.size(); i++) {
            ppg_desc[0].push_back(statistic[i]); 
            ppg_desc[1].push_back(i);
        }
        sort(ppg_desc[0].begin(), ppg_desc[0].end());
        if (ascend == false)
        reverse(ppg_desc[0].begin(), ppg_desc[0].end());
        //
        for (int i = 0; i < statistic.size(); i++) {
            //
            bool lok = false;
            //
            for (int f = 0; f < statistic.size(); f++) {
                //
                for (int d = 0; d < ppg_desc[2].size(); d++) {
                    //
                    if (i == ppg_desc[1][d]) { 
                        //
                        lok = true; 
                        //
                        for (int s = f + 1; s < statistic.size(); s++) {
                            //
                            if (statistic[s] == ppg_desc[0][i]) {
                                lok = false;
                                f = s;
                                if (f >= statistic.size()) f = statistic.size() - 1;

                            }
                            
                        }
                    }
                    
                }
                //
                //if (stats[6][f] == ppg_desc[0][i] && lok == false) ppg_desc[1][i] = f, ppg_desc[2].push_back(ppg_desc[1][i]), cout<<i<<"-";
                if (statistic[f] == ppg_desc[0][i] && lok == false) ppg_desc[1][i] = f, ppg_desc[2].push_back(i);
            }
            
        }
        //

        for (int i = 0; i < number; i++) {
            cout << i << ".) " << ppg_desc[0][i] << " - " << names[0][ppg_desc[1][i]] << endl;
        }
        //
    }
genpfault
  • 51,148
  • 11
  • 85
  • 139

1 Answers1

0

What you basically need is a list of the indices, sorted by one of the vectors content.

This can be achieved with a variant of std::sort taking function objects / lambdas; something like this:

std::vector<int> score = {2,4,3};
std::vector<std::string> names = {"a", "b", "c"};
std::vector<int> V(N);
std::iota(V.begin(),V.end(), 0); // fill V with values increasing by 1
std::sort(V.begin(),V.end(), [&](int i,int j){return score[i]<score[j];} );
std::cout << "Names sorted by score: " << names[V[0]] << ", "<< names[V[1]] << ", "<< names[V[2]] << "\n";

As you can see, you can use the indices in V, now sorted by score, as index into names.

See example at cpp.sh

Inspiration: https://stackoverflow.com/a/40183830

An alternative solution, as suggested in comments, would be to include all values that belong together (both names and scores in my example) into a struct, then have a vector of this struct, and then again use above sort method with a specialized sorting function.

struct Player { std::string name; int score; }
std::vector<Player> players;
//... insert some players
std::sort(players.begin(), players.end(), [](auto const & p1, auto const & p2) { return p1.score < p2.score; });
// .. and now all your data is sorted by score!
codeling
  • 11,056
  • 4
  • 42
  • 71