Help in Sorting an Array of strings on the basis of Numbers in the string

I have a .txt File that will hold data in the format:
Name: Some Name   Time: Some Time    Score :- Score

It has many lines of such Text, each terminating with a Return Carriage ('\r').

I have put the - after the Colon after Score to use it as a delimiter while I segregate the scores to compare their values.

Now this is what I have done already:
1) I retrieve one line into a vector of strings.
2) I Put that string into a stringstream, and then convert it to an double.
3) I store that double into another vector of doubles.

But I can't figure out how to rearrange the Vector of strings with respect to a sorted vector of the doubles.

Any help??
Last edited on
Sorry, not quite sure what you mean.
You've got a vector of strings holding names and another vector of doubles holding scores?
And you want to sort the scores, but then they go out of sync with the names?
If so I think that's a design problem. Wouldn't you be better storing names and scores together in a user-defined class, and having a vector of those? You can supply this class with an operator<() function so it'll work with std::sort.
Sorry. Should have explained my problem a bit more clearly...
Well, anyways, I was keeping a record of scores of players in a simple console game I am making.

So the line:
Name: Some Name   Time: Some Time    Score :- Score

is stored into a string.
From it I get the Score and put it in another vector.

Now I want to arrange all the scores in order of decreasing scores and store them into the file back again.

So what I want to do is Like this:

In File:
Name: abc Time: 12  Score :- 10
Name: xyz Time: 15  Score :- 14


To Vector:
1
2
3
4
5
6
7
8
9
10
11
vector<strings> High;     
//After strings are Pushed_Back
High[0] = "Name: abc Time: 12  Score :- 10";
High[1] = "Name: xyz Time: 15  Score :- 14";

//Parsing and all....

vector<double> Score;
//After scores are Pushed_Back
Score[0] = 10;
Score[1] = 14;


After Rearrangement (This is what I am unable to achieve):
1
2
High[0] = "Name: xyz Time: 15  Score :- 14";
High[1] = "Name: abc Time: 12  Score :- 10";


By comparing corresponding Values of:
(This is I sort this vector, and want to rearrange the High vector in the same way as this one has been)...
1
2
Score[0] = 14;
Score[1] = 10;


NOTE: The above is just an example and not the actual code.
Last edited on
Hi Nisheeth

Erm, I stand by my original answer ;)
I think your main problem is you're separating scores from names - you need to keep them together. Here's a short program to demonstrate what I mean. I'm cheating because I'm not parsing the strings but you're fine with that anyway. I'm using ints for scores as well but it'll work just as well with doubles.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <algorithm>
#include <iostream>
#include <vector>

struct Entry
{
    std::string stats;
    int score;
    
    Entry( const std::string& s ) : stats(s)
    {
        // parse string, extract score and place in 'score' variable
    } // Entry
    // I'm going to cheat by putting scores in without parsing.
    Entry( const std::string& s, int d ) : stats(s), score(d) {}
    
    int operator<( const Entry& e ) const { return score > e.score; }
    
}; // struct Entry

int main()
{
    std::vector<Entry> entries;

    const char* names[] = { "Snoopy, 47", "Woodstock, 13", "Sally, 12",
    "Charlie, 30", "Lucy, 27", "Linus, 41" };
    int scores[] = { 47, 13, 12, 30, 27, 41 };
    for ( int i = 0; i < 6; ++i )
    {
        Entry e( names[i], scores[i] );
        entries.push_back(e);
    } // for

    std::sort( entries.begin(), entries.end() );
    for ( int i = 0; i < entries.size(); ++i )
    {
        std::cout << entries[i].stats << "\n";
    } // for

    return 0;

} // main 


So by keeping those entry strings (lines from your file) and scores together in one object (an Entry), I just sort the vector of Entry objects and that's it - everything rearranges itself. I'm sure that's your answer.
Regards, keineahnung
You want to sort the whole thing by score. Create a class and overload operator< so you can use std::sort() to sort by score.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class HighScore
{
private:
    string m_name;
    double m_time; //Or make it an it... whatever.
    double m_score; //Ditto.

public:
    HighScore(const char *highScoreLine)
    {
        //Add the parsing of the string here and store the name in m_name,
        //the time in m_time and the score in m_score.
    }

public:
    //Add property GET accessors; add SET accessors if the data is writeable too.
    string Name() { return m_name; }
    double Score() { return m_score; }
    double Time() { return m_time; }

public:
    //Now the operators.
    bool operator< (const HighScore& op2) const { return m_score < op2.m_score; }
};
....
//Now you can just read the file one line at a time and store HighScore objects in a vector.
vector<HighScore> hiScores;
....
while (file.good())
{
    getline(file, strLine); //strLine is of type std::string.
    hiScores.push_back(HighScore(strLine.c_str()));
}
//Now sort by score:
std::sort(hiScores.begin(), hiScores.end());
//Done! 
LOL! Almost the exact same answer.

Well, now that I realize, mine orders in ascending order. Forgot you wanted descending order. Easy fix: Invert the result of operator<, or change < for > inside the operator<'s definition.
Last edited on
@webJose - what is they say about great minds?! (and not so great like mine ;)
Cheers, keineahnung
Thanks Both!
I am sure I could have designed the class by myself after some time, but you do make it easier that it is.
Thanks again!!
Topic archived. No new replies allowed.