I have a problem with sorting a vector in a specific order.
As seen below I am putting 4 strings into a vector like this.
The result of the sorting that I am after is like this:
(Highest Value at the top and the Lowest Value at the Bottom)

20A
3A
-3A
-20A

But the Sort will be like below instead:
(It seems that the negativ values is Correct but not the positive as I want it)

3A
20A
-3A
-20A

I have also tried .begin .end as sort but this will also be wrong.
How could a sort like this be possible. Thanks !

std::vector<string> Sorting;

 std::string One = "-20A";
 std::string Two = "20A";
 std::string Three = "-3A";
 std::string Four = "3A";

	 Sorting.push_back(One);
	 Sorting.push_back(Two);
	 Sorting.push_back(Three);
	 Sorting.push_back(Four);

	 std::sort( Sorting.rbegin(), Sorting.rend() );

Recommended Answers

All 12 Replies

I'm confused at what you want.

"3A" > "20A" > "-3A" > "-20A"

The algorithm is working properly.

[edit]
Oh, I get it.

Remember, strings and numbers are not the same thing. You'll have to convert to numbers and sort on that.

The reason the sort comes out screwy is because 3A is actually less than 20A. If you want them sorted the other way around you have to make the strings the same size, like this:

20A
03A
-03A
-20A

Then the above will sort as, which is exactly the same order as you originally reported.
03A
20A
-03A
-20A

With the code that I have below, the output of the sort will look like this and this is not exactly how I want it to sort:

20.32,bc4
12.44,ffdasd34
03.55,defg32
-3.52,c4
-20.45,ab555
-12.44,es48

How the sort that I am after should look like will look like this instead:

20.32,bc4
12.44,ffdasd34
03.55,defg32
-3.52,c4
-12.44,es48
-20.45,ab555

The strings that will be sorted Always begin with a number and a "," followed by letters and numbers.
What I am interested in is that the sort will go from(Numerically) highest value to lowest considering what the strings begin with before the "," like:

20.32
12.44 //Numerically less than 20.32
03.55 //Numerically less than 12.44
-3.52 //Numerically less than 03.55
-12.44 //Numerically less than -3.52
-20.45 //Numerically less than -12.44

I am not sure if it is possible to understand what I am trying to do. I have a bit of a problem to make this work.

std::vector<string> Sorting;

std::string One = "-20.45,ab";
std::string Two = "20.32,bc";
std::string Three = "-3.52,c";
std::string Four = "03.55,defg";
std::string Five = "-12.44,es";
std::string Six = "12.44,ffdasd";

Sorting.push_back(One);
Sorting.push_back(Two);
Sorting.push_back(Three);
Sorting.push_back(Four);
Sorting.push_back(Five);
Sorting.push_back(Six);

std::sort( Sorting.rbegin(), Sorting.rend() );

With the code that I have below, the output of the sort will look like this and this is not exactly how I want it to sort:

20.32,bc4
12.44,ffdasd34
03.55,defg32
-3.52,c4
-20.45,ab555
-12.44,es48

How the sort that I am after should look like will look like this instead:

20.32,bc4
12.44,ffdasd34
03.55,defg32
-3.52,c4
-12.44,es48
-20.45,ab555

The strings that will be sorted Always begin with a number and a "," followed by letters and numbers.
What I am interested in is that the sort will go from(Numerically) highest value to lowest considering what the strings begin with before the "," like:

20.32
12.44 //Numerically less than 20.32
03.55 //Numerically less than 12.44
-3.52 //Numerically less than 03.55
-12.44 //Numerically less than -3.52
-20.45 //Numerically less than -12.44

I am not sure if it is possible to understand what I am trying to do. I have a bit of a problem to make this work.

std::vector<string> Sorting;

std::string One = "-20.45,ab";
std::string Two = "20.32,bc";
std::string Three = "-3.52,c";
std::string Four = "03.55,defg";
std::string Five = "-12.44,es";
std::string Six = "12.44,ffdasd";

Sorting.push_back(One);
Sorting.push_back(Two);
Sorting.push_back(Three);
Sorting.push_back(Four);
Sorting.push_back(Five);
Sorting.push_back(Six);

std::sort( Sorting.rbegin(), Sorting.rend() );

I understand what you are trying to do, I believe. The problem is as Duoas and Ancient Dragon mentioned. The method that C++ is using to compare two elements is not the method you want. Here is a link to the sort function:
http://www.cplusplus.com/reference/algorithm/sort.html

From this link, I have underlined the relevant line as far as I see it:

Sort elements in range

Sorts the elements in the range [first,last) into ascending order.

The elements are compared using operator< for the first version, and comp for the second.

Elements that would compare equal to each other are not guaranteed to keep their original relative order.

Parameters

first, last
Random-Access iterators to the initial and final positions of the sequence to be sorted. The range used is [first,last), which contains all the elements between first and last, including the element pointed by first but not the element pointed by last.
comp
Comparison function object that, taking two values of the same type than those contained in the range, returns true if the first argument goes before the second argument in the specific strict weak ordering it defines, and false otherwise.

I have never done this, but possibly a solution would be to write your own < operator to override C++'s < operator, which in this case would be comparing the strings by ascii value. I have never tried this, but that is what I would try. In your case, the < operator would be to convert the characters before the comma to a double, then compare using the numerical < operator. That would be my first try.

You could write a simple comparison function that you can supply to the std::sort().

bool MyCompare(const string & lhs, const string & rhs)
{
    // std::sort() calls this function each time it needs to determine the 
    // order of two items ..
    //
    // Todo: compare here the strings in the fashion you need
    // You might e.g. use stringstream to extract the two numerical values 
    // the sort is based on.
}

// To use the above function, you call ...
std::sort(Sorting.begin(), Sorting.end(), MyCompare);

In
http://www.cppreference.com/cppalgorithm/sort.html
is a short example of this which uses an vector<int>.

EDIT: Umm .. didn't see VernonDozier's post ..

for std::sort you can write your own comparison function. Convert what is before the comma to float and do float compare

bool compare_on_asscending_value( const string& s1, const string& s2)
{
    float f1, f2;
    stringstream str1(s1);
    stringstream str2(s2);
    str1 >> f1;
    str2 >> f2;
    return (f1 > f2) ? true : false;     
}

int main()
{
std::vector<string> Sorting;

std::string One = "-20.45,ab";
std::string Two = "20.32,bc";
std::string Three = "-3.52,c";
std::string Four = "03.55,defg";
std::string Five = "-12.44,es";
std::string Six = "12.44,ffdasd";

Sorting.push_back(One);
Sorting.push_back(Two);
Sorting.push_back(Three);
Sorting.push_back(Four);
Sorting.push_back(Five);
Sorting.push_back(Six);

std::sort( Sorting.begin(), Sorting.end(), compare_on_asscending_value );

for(int i = 0; i < Sorting.size(); i++)
   cout << Sorting[i] << "\n";

}

Note: I borrowed the idea from vijayan121, here.

You obviously didn't bother to read my previous post. Compile and run it yourself to see how it works.

You can't compare the strings directly, but have to convert to floats and compare the floats.

also, use begin() instead of rbegin(), and end() instread of rend()

(I was missing your post because I was reading the others for long time wihout updating the page.)
I have to ask, does this comparison work within a managed area wich meens that I can put the below code like this (private: ) and then inside a buttonControl use the std::sort method with 3 arguments ?
Or does this only work with native code (std:: )
Why I was thinking of this was because you wrote: int main()

I tried to do this sort but std::sort expects only 2 arguments in the Error message I got ?
(However the ComparisonCode itself did compile with (private: bool etc... )

private: bool compare_on_asscending_value( const string& s1, const string& s2) 
{ 
   float f1, f2; 
   stringstream str1(s1); 
   stringstream str2(s2); 
   str1 >> f1; 
   str2 >> f2; 
   return (f1 > f2) ? true : false; 
}

If you are sorting on private or protected class elements then you need the comparison function (whether it is an overloaded < or a normal function you pass to the sort() algorithm) to be a friend of the class.

Likewise, as to your explicit question, the comparison function itself must be visible to the scope in which it is used. If you really want to keep it private, make your class have a sort() function:

class Quux
  {
  private:
    vector<string> whatever;

    bool compare_on_ascending_value(
      const string& s1,
      const string& s2
      ) const
      {
      float f1, f2;
      stringstream str1(s1);
      stringstream str2(s2);
      str1 >> f1;
      str2 >> f2;
      return (f1 > f2);
      }

  public:
    void sort()
      {
      std::sort(
        whatever.begin(),
        whatever.end(),
        compare_on_ascending_value
        );
      }
  };

Hope this helps.

I am sorry for not really understand this. I was writing private: but it is not needed to make it private, peheps I can use public: for the sort:: ?
The compiler said also that:
:Quux' : a native type cannot be nested within a managed type

I think it is best for me to take it from the beginning, simple.
Below I have code under a buttoncontrol.
I want to sort the vector: "Sorting2" so the output will be in ascending order.
I know I have to use a comparisonmethod wich will be a 3:rd argument (compare_on_asscending_value).

The output should look like: (Ascending Order)
22.1
1.1
-1.1
-22.2

So what is missing is the comparisonmethod and now I wonder how this will be written.
With private, public or protected to make this compile and be seened by the std::sort
inside my buttoncontrol.
Thank you...

std::string a = "1.1";
	std::string b = "22.2";
	std::string c = "-1.1";
	std::string d = "-22.2";

	std::vector<string> Sorting2;
	Sorting2.push_back(a);
	Sorting2.push_back(b);
	Sorting2.push_back(c);
	Sorting2.push_back(d);

       std::sort(Sorting2.begin(), Sorting2.end(), compare_on_asscending_value);

'Quux' is a metasyntactic variable. Replace it with whatever the name of your class. Just like 'whatever': replace it with the name of your list/vector/array/whatever.

[edit]Since you have no reason to keep the comparison function private, make it public.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.